Hangi noktada döngüler içinde döngüler olması tabudur?


23

Sadece merak. Şimdiye kadar sahip olduğum en büyük şey bir for döngüsü içindeki for döngüsü idi, çünkü bunu Linus Torvalds'dan okuduktan sonra :

Sekmeler 8 karakterdir ve bu yüzden girintiler de 8 karakterdir. Girinti 4 (veya hatta 2!) Karakterleri derinleştirmeye çalışan sapkın hareketler var ve bu PI değerini 3 olarak tanımlamaya çalışıyor.

Gerekçe: Girintinin arkasındaki bütün fikir, bir kontrol bloğunun nerede başladığını ve bittiğini açıkça tanımlamaktır. Özellikle 20 saat boyunca ekrana baktığınızda, büyük girintileriniz varsa, girintinin nasıl çalıştığını görmeyi çok daha kolay bulacaksınız.

Şimdi, bazı insanlar 8 karakterli girintilere sahip olmanın kodu sağa doğru çok ilerlettiğini ve 80 karakterlik bir terminal ekranında okumayı zorlaştırdığını iddia edecekler. Bunun cevabı, 3'ten fazla girinti seviyesine ihtiyacınız varsa, yine de batırdığınız ve programınızı düzeltmeniz gerektiğidir.

https://www.kernel.org/doc/Documentation/CodingStyle

Üçüncü bir döngü katmanına gitmemin kabul edilemez bir uygulama olduğunu düşündüm ve kodumu yeniden yapılandırdım (Öncelikle Qt).

Linus şaka mı yapıyordu?

Dile ya da uygulamaya bağlı mı?

Kesinlikle üç veya daha fazla döngü seviyesine ihtiyaç duyan bazı şeyler var mı?


8
Girintiden döngü düzeylerine neden atladığınıza şaşırdım. Girinti hakkında geniş bir alıntı yaptınız ve bu aniden iç içe döngüler hakkında bir soru takip ediyor.
Pieter B

5
Linus muhtemelen bu bölümde şaka yapmaz, ancak bunun sadece bir stil rehberi olduğunu ve aynı stil rehberinin "Çekirdek kodlama stilinin süper basit olduğunu", yani diğer stillerden daha fazla olduğunu vurguladığını unutmayın.

5
@Akiva 4 iç içe döngüye sahip olmadan 4 boyutlu bir matristen geçemezsiniz. Birisinin sahip olabileceğiniz iç içe döngü miktarını sınırlaması çok delice. Linus açıkça çok genel davranıyordu ve okuduğunuz her şeyi kutsal bir kutsal kitap olarak kabul etmemelisiniz.
Alternatex

9
@Alternatex 4 döngüye ihtiyacınız var, onların sözcüksel olarak yuvalanmış olmaları gerektiği anlamına gelmez . Kodun nasıl düzenleneceğinden, yürütmeyle ilgili olarak bahsettiğimiz alıntıdan açıkça anlaşılıyor.

4
@Delnan 4 iç içe geçmiş döngü görsel olarak hoş olduğunu söylemiyorum ve bunun için başka yolların olduğunu biliyorum ama OP'nin Linus'un sözlerini tam anlamıyla nasıl aldıklarını aptalca buluyorum. 4. girinti seviyesi = dünyanın sonu. Bana bir mola ver.
Alternatex

Yanıtlar:


19

Çekirdek basit algoritmaları şiddetle tercih eder

Çeşitli algoritmalar döngüler içinde derinlemesine iç içe geçmiş döngüler gerektirebilirken, Linux çekirdeği bağlamında (alıntıların söylendiği) genel olarak hızlı gerçek zamanlı yanıtlara ihtiyacınız vardır. Bu bağlamda, derin iç içe geçme, kod akışının bu etki alanı için çok karmaşık olduğunu ve okunabilirlik veya girinti sorunları değil yürütme özellikleri nedeniyle değiştirilmesi gerekebileceğini gösteren bir koku.

Ayrıca, Linux çekirdeği denetlenebilirlik ve test gereklerine gelince çoğu uygulama kodundan farklı - ve böylece tercih edeceğini değil tek işlevinde 4+ düzey iç içe algoritma var. Olası tüm kontrol akışı ve kenar durumları da dahil olmak üzere her kod parçasının tam olarak ve ayrıntılı olarak ne yaptığını görmek açık olmalıdır . Derinden iç içe geçmiş kod bunu engeller.


Yani, C gibi daha düşük seviyeli dillerle, derinlemesine iç içe döngüler genellikle daha becausedüşük seviyeli dilleri kullanan daha tabu projelerinin daha basit algoritmalara odaklanan bir kodlama stilinden faydalandığını düşünüyor musunuz?
Akiva,

4
@Akiva Daha düşük seviyeli dillere veya C'ye bağlar, ancak kod alanına değil. Ben de benzer kurallar için de geçerli olacak düşünüyorum herhangi bir kod yazarken dilin gerekir sağlam olması, güvenlik odaklı ve diğer şeyler pahasına denetlenebilir. Örneğin, Java veya Haskell ile yazılmış bir şifreleme kütüphanesi, işleri mümkün olduğu kadar basit tutan, yerleştirmeyi sınırlayan ve her şeyi olası sonuçlarıyla kolayca analiz edilebilen parçalar halinde ayırmaya çalışan bir tarzda da yazılmalıdır.
Peteris

Çok anlayışlı ve faydalı bir yorum / cevap. Sadece merak; Bugün düşük seviyeli bir dili kullanan, sağlam, denetlenebilen ve güvenli olmaya odaklanmayan ne tür bir proje yapıldı?
Akiva,

7
Örneğin @Akiva, C'yi sadece performans nedenleriyle kullanmak isteyebileceğiniz, sağlamlık veya güvenlik ile ilgilenmediğinizden dolayı, kontrollü koşullarda çalıştırılacağı için makine öğrenme kodu. Ayrıca, küçük gömülü mikro denetleyicilerde basit işletme işlevselliği uygulamak - pratikte bu genellikle kalite ve güvenlik pahasına özelliklere ve geliştirme hızına odaklanmak gibi bir işe sahiptir, ancak düşük seviyeli dilleri kullanır.
Peteris

49

Bir dereceye kadar, bu alıntıyı "Sekmeler 8 karakterdir" de ciddiye almayı bıraktım . Tüm tabulatörler, sabit sayıda karakter olmadıklarıdır (eğer varsa, bir sekme bir karakterdir). Ne saçmalık! Benzer şekilde, tamamen (Hızlı bir sabit-ve-kuralı belirlemiş olduğu kadar "girinti üç düzeyde" bir sert ve hızlı-kuralı belirlemiş aklı başında olduğuna ikna olmadım şey aklı başında).

Ancak, girinti sizin düzeylerini sınırlayan olduğunu size bir sürpriz olarak gelmelidir bir genel makul bir öneri de değil.

Sonuç olarak, eğer programınız üç seviyede tekrarlamaya ihtiyaç duyuyorsa, programınızın ihtiyaç duyduğu şey budur . Alıntı ruhu, projenizden bu gereksinimi sihirli bir şekilde hafifletmek değil, mantığınızı fonksiyon ve türlere dönüştürmek ve böylece kodunuzun ters ve daha etkileyici olmasını sağlamaktır.

Bu sadece girinti seviyeleri ile ilgili yukarıda verilen aynı kılavuza geri beslenir. Bu, kodunuzu nasıl yapılandırdığınız ve yıllar boyunca değiştirebileceğiniz okunaklı, bakımı kolay ve eğlenceli hale getirme ile ilgilidir.


6
Sekmelerin 8 karakter olduğunu belirten "bildiri" nin özellikle çekirdek geliştirme bağlamında olduğuna inanıyorum. Bu alıntı, belirli bir proje için kodlama kılavuzundan alınmıştır ve genel bir kullanım kılavuzu olması amaçlanmamıştır ve bu nedenle oldukça tartışılması beklenmektedir.
Lie Ryan

6
@LieRyan: O zaman hala zor - bir şey için bir kodlama kılavuz sekmelerimi ne kadar geniş koyduğumu belirleyen hiçbir iş yok! Ama Linus'un bunu bildiğinden şüpheleniyorum.
Monica ile

6
ve tabii ki en dile bağlı - sizin sınıfta senin isim alanı içinde girinti ve hatta önce yönteminde .. Eğer girinti 3 seviyelerinde Zaten o yaygındır c # konuşmak kontrol akım tablosu organları olma konusunda girintili.
PeterL

3
@LightnessRacesinOrbit "Sekmeler 8 karakterdir" yorumunu, editörünüzde kişisel olarak sekmeleri 8 genişlikte görüntülemeniz gerektiği anlamına gelmez, ancak stil kılavuzundaki diğer kuralların amacı için (örneğin, "Satırların uzunluğu sınırındaki" 80 sütun ve bu kesinlikle tercih edilen bir limit. ") sekmeleri 8 sütun olarak ele almalı, bu fonksiyon çağrılarındaki argüman uyumu ile ilgili diğer kurallarla da ilgilidir. Yine, bu çizginin amacının sizi sekmeleri bu şekilde görüntülemeye zorladığını düşünmüyorum, daha önce 4 geniş sekme ile çekirdek düzeltme eki yaptım ve kodu tekrar akıttım.
Vality

4
@underscore_d: Yanlış olduğum anlaşılıyor: Outside of comments, documentation and except in Kconfig, spaces are never used for indentation, and the above example is deliberately broken.- OP'deki alıntıdan 6 paragraf aşağı.
slebetman

16

Mesele, akış kontrol yapılarının tümü ile aynıdır: eğer kodun anlaşılması zorsa, yeniden düzenlemelisiniz. Çok boyutlu bir dizinin bazı basit manipülasyonlarını yapıyorsanız, en içteki döngüdeki mantık basit olduğu sürece, beş veya altı derinlikte iç içe olan döngüler olması uygun olabilir. Bununla birlikte, bazı karmaşık iş mantığını işliyorsanız ve döngünüzün gövdesi bir düzine satır veya daha fazla ise, o zaman muhtemelen birden fazla döngüyü derinlemesine yuvalamak istemeyeceksiniz. Kodun döngüsel karmaşıklığını hesaplamayı deneyebilirsiniz , ancak gerçekte asıl konu, söz konusu kodun okunabilirliği ve bakımıdır .


11
Kesinlikle. Torvalds'ın bir lanet olduğunu öne sürmek çok kolay. (Tabii ki.) Zevkiniz için çok katı olabilir, ancak gerçek sorunlara neden olan gerçek bir gelişme endişesini tarif ediyor. Ne diyorsa onu yapmak zorunda değilsin ama neden söylediğini düşünmelisin.
Roger

7
@ScantRoger Aslında, Torvalds-alıntı sadece onun mizah anlayışını anlamadığınız takdirde çok sert sesler. Hatırladığım kadarıyla, daha önce aynı belgede, GNU kodlama stili kurallarının bir kopyasını, sadece bir tür törende yakmak için basılmasını önerir. Bunu ciddiye almazsın, değil mi? Bu alıntıda asıl amacı, linux çekirdeğin girintisini sekiz boşluk, daha fazla ve daha az hiçbir şey olmayacak şekilde tanımlamaktır. Son cümle sadece bu noktanın altını çizmek, daha fazla girinti seviyesi kullanmamanız gerektiğini söylememek değil - sertlik ima etmeyin.
cmaster

1
@cmaster Bağlam için teşekkürler, doğru! Sorgunuza cevap olarak hiçbir şeyi ciddiye almıyorum. ;)
Azalıyorum Roger

2
@cmaster ve sonra biri github çekme isteklerine ve taahhüt mesajlarının satır uzunluğuna verdiği yanıtları okur. O tam bir somun davası.
Gusdor

3
GNU kodlama kurallarını törensel olarak yakmak aslında gerekli olmayabilir, ancak zamanın herhangi bir noktasında tamamen sırayla gerekli olabilir.
dmckee

13

Linus şaka mı yapıyordu?

Eser, yazarın ciddi uygulayıcılar arasında kodlama stilinin nasıl ele alındığına aşina olduğunu gösteren eğlenceli bir tarzda yazılmıştır: Hepimizin tercihleri ​​vardır ve onları kuduz bir şekilde savunuruz, fakat en azından kısmen yanağında dil ile savunuruz. Tamamen çok iyi anlıyoruz, bunun sadece kişisel zevk meselesi olduğunu. Pek çok kelimeyle "Coding style is very personal, and I won't _force_ my views on anybody"- en azından şahsen koruduğu kodun dışında olduğunu söylüyor. Ancak belirli bir projede stil tutarlılığı çok iyi bir fikir. Belirli bir fonksiyondaki çoklu stillerle uğraşmaktan hoşlanmadığım bir stile kodlamayı tercih ederim.

İşte net bir şekilde oynak bir yazı örneği:

However, there is one special case, namely functions: they have the
opening brace at the beginning of the next line, thus:

int function(int x)
{
    body of function
}

Heretic people all over the world have claimed that this inconsistency
is ...  well ...  inconsistent, but all right-thinking people know that
(a) K&R are _right_ and (b) K&R are right.  Besides, functions are
special anyway (you can't nest them in C).

Oyuncu (1).

Kontrollü bir şekilde kontrolden çıkmamaya özen göstermeye çalışmanız iyi bir fikir olabilir, ancak maksimum üç seviye hiperbolik olabilir. Çekirdek kaynağını greplemeyeceğim ve dört sekme karakterinin dizisini saymayacağım, ama Torvalds'ın yazdığı en az birini bulabileceğinize bahse girerim.

Öte yandan, eğer biri Linux çekirdeğini sık sık üç girinti seviyesini aşmadan yazabiliyorsa, üç seviyeli bir sınır, yalnızca sizi nereye götürdüğünü görmek için kendi kodunuzda bir süre denemeye değer bir egzersiz olabilir. Bu cinsiyet değişikliğine benzemiyor, biliyorsun. Bu bir ömür boyu bağlılık değil.

İnternette Torvalds'tan (2) çok daha iyi programlamayı anladığını düşünen birisiyle karşılaşırsanız, ne tür insanların İnternet üzerinde büyük konuşmayı sevdiğini bilirsiniz.

Öte yandan, sekiz boşluklu sekmeler hakkında suçlu olarak yanlış. Bu, sınırlamada tutulması ve bir yarıktan beslenmesi gereken bir erkeğin övgüsüdür. Dört boşluk açıkça doğrudur.

(1) Ancak elipslerin önüne ve boşlukları onlardan sonra ve iki noktadan sonra tam bir duraktan sonra nasıl boşa koyduğunu not edin. YANLIŞ, YANLIŞ, YANLIŞ. Ve sonra, heretik yapmayı kısaltmak için sert bir safra yarattı. Heretic sensin, Torvalds! O SENSİN!

(2) “ Kaynak kontrol sisteminin nasıl tasarlandığını anlamak ” hakkında konuşmak istiyorsanız, tartışma için bir yer olabilir.

Not: Aynı düzenlemeyi defalarca gönderen değerli kullanıcı: Alıntılanan materyalin biçimlendirmesi, tam olarak olması gerektiği gibi yazar olarak tutulur. Bunun nedeni, sabit genişlikli metnin biçimlendirmesini makul miktarda bir düşünce vermiş olan biri tarafından sabit genişlikli metinde yazılmış sabit genişlikli metnin biçimlendirilmesiyle ilgili bir denemeden kaynaklanmaktadır. Biçimlendirme, yazarın amacının bilinçli ve kasıtlı bir parçasıdır ve konuyla ilgilidir.

Ek olarak, bu biçimlendirmeye kendi metnimde geri döndüm. Ön biçimlendirmeyi kaldırırsanız, dipnotum (1) anlamsızlaşıyor. Önceden biçimlendirme kaldırılırsa, dipnotumdaki (1) cümlenin sonunda tam durduktan sonra boşluk çiftlerine atıfta bulunan metin olmalıdır. Bu dipnotu çıkarmanın bir gerekçesini yine de yazdım, göründüğümden daha az komik olduğu için görebiliyorum. Ancak biçimlendirmeyi dipnot kaldırmadan kaldırmak için yararsızdır.


3
Harika cevap + .
2'yi

2
Linus'un belirttiğiniz giriş paragrafı çok önemlidir, bu yüzden bunu yaptığınız için teşekkür ederiz! İlk cümle de çok bağlam için önemli, özellikle olduğunu düşünüyorum preferred coding styleyanı sırabut this is what goes for anything that I have to be able to maintain
Chris Haas

9

Linus'un çok keskin bir konuşma tarzı ve kuru bir mizah anlayışı var, ama bu durumda şaka değildi. Bir algoritmanın iki seviyeden daha derin bir yuvaya ihtiyaç duyduğu durumlar vardır , ancak kodunuzu girintiden başka yolları kullanarak da yapabilirsiniz. Linux çekirdeği stili kılavuzu, iç içe geçmiş döngüleri korumanın zorluğundan dolayı bu diğer yöntemleri kuvvetle tercih eder ve Linus'un burada söylediği şey budur.

Bazı alternatif yöntem örnekleri için özyineleme kullanabilir, iç döngüleri kendi işlevlerine ayırabilir veya ara veri yapıları yapabilirsiniz.

Aşırı iç içe geçme, yazılması daha kolay ancak okunması zor olan durumlardan biridir. Büyük bir sekme derinliği ayarlamak, Linus'un yazmayı daha da sinirlendiren bir yoludur.


3

Soruyu soran birisi için tavsiyenin, sormayan birine göre farklı olduğu pek çok soru vardır. "Hiç iki seviyeden fazla derinlemesine iç içe geçmiş döngülerim var mı?" Diye sorarsanız, o zaman sizin için bu soruyu soran kişi, cevabım HAYIR. Eğer sorarsan, yapma. Sormanız gerekmeyen deneyime sahipseniz, her durumda doğru cevabın ne olduğunu bilirsiniz. Ve cevabı kabul etmiyorsanız tartışmayın, çünkü cevap sizin için değildir.


1

Bu, köpeği sallayan kuyruğun bir ders kitabı durumunda görünmektedir.

Eğer 80 karakterlik bir ekrana sahipseniz, tabii ki kod için en iyi yapıyı üretmemiş olsa bile kodu elinizden geldiğince uygun hale getirmeye çalışacaksınız .

Puanlarınızın geri kalanıyla mücadele:

Kabul edilemez bir uygulama olduğunu düşündüm.

Bence bu konuyu çok okuyorsun. Bağlamı doğru bir şekilde anlamadan okuduğunuz her şeyi okuma dürtüsüne direnin.

Şaka mı yapıyordu?

Bağlamı belirlemek zor, ama yukarıdaki asıl noktamı gör.

Dile ya da uygulamaya bağlı mı?

Çok çok. Bir terminale (veya terminal emülatörüne) kodlama olasılığınız olan herhangi bir ana bilgisayar / orta seviye dilini alın.

Kesinlikle üç veya daha fazla döngü seviyesine ihtiyaç duyan bazı şeyler var mı?

Evet, bazı kaba kuvvet algoritmalarında çok yaygındır. Project Euler'daki Problem 31'e bakınız . Bu, bir kaç döngü (8 kesin) kullanarak kaba kuvvetle çözülebilen bir problemin klasik bir örneğidir.


1
Problem 31, bruteforce gerektirmez ve dinamik bir programlama algoritması kullanılarak çözülebilir (düzenleme: bir bruteforce algoritması kullanıyorsanız kod yapınızın en iyi olmadığı anlamına gelir). Ayrıca, Linus'un anlamı, eğer kodunuz çok fazla girinti gerektiriyorsa, kod için en iyi yapı olmayabilir.
Vincent Savard

2
@ VincentCavard Asla kaba kuvvet gerektirdiğini söylemedi . 2. puanınıza katılmıyorum - bazen bazı durumlarda en etkili olanı değil, en açık ve en özlü yaklaşımdır.
Robbie Dee

1
Bu tür bir problemle genelde döngülere girmem. Sanırım 20 yuvalanmış, yazması kesinlikle önemsiz olan ve girintiler yokmuş, böylece döngüler neredeyse aynıydı.
gnasher729

1
@RobbieDee: Demek istediğim, birçok döngü tarafından çözülen bir sorun örneğiniz, algoritmanızın, çok fazla girinti gerektirmeyen dinamik bir programlama çözümü kadar verimli olmadığıdır. Böylece, Linus'un dediği gibi, girinti seviyeleriniz daha iyi bir çözüm kullanarak temizlenebilir. Siz de ikinci noktayı yanlış anladınız çünkü söylediklerinize katılıyorum. Bazen en iyi çözüm budur. Bazen sık değildir ve muhtemel değildir.
Vincent Savard

1
Linus alıntı hemen hemen açıkça açıkça gösteriyor ki, eğer bazı kodlar o Problemi-31'i zorlama gibi bir şeyi gerektiriyorsa, yine de berbat olursun - hızlı ve basit olmayacak - ve çekirdek işlemlerinin hızlı ve basit olması gerektiğini söyler . Çekirdeğe herhangi bir O (n ^ 4) algoritması dahil edilmesi, önemli bir performans riski veya hizmet reddi sorunudur, bu nedenle bu öneri, basitçe bunun Linux'ta temelde uygunsuz olabilecek ve istenebilecek bir kod işareti olduğu konusunda uyarır.
Peteris

0

Linus şaka mı yapıyordu?

Hayır, bunlar resmi kurallar.

Dile ya da uygulamaya bağlı mı?

Kodlama kuralları genellikle dile ve uygulamaya bağlıdır, ancak derine yerleştirilmiş kod her zaman okuyucuyu vergilendirir.

İç içe kodla ilgili sorun, genel olarak döngüsel karmaşıklığı arttırmasıdır: yani, kod ne kadar iç içe geçmişse, işlev içinde daha fazla potansiyel yürütme yolu vardır. Potansiyel uygulama yollarının birleşimsel patlaması, kod hakkında gerekçeyi zorlaştırır ve bu nedenle genel olarak kaçınılmalıdır.

Peki neden 3? Öznel bir kodlama kılavuzunun uygulanması zor hem de otomatik olarak zorlaştırılabilir. Nesnel bir kodlama kılavuzunun maksimum girinti seviyesine ayarlanması, bir sayı üzerinde anlaşmaya varmayı gerektirir: Linux çekirdeğinde 3 seçtiler.

Bu keyfi ve onlar için yeterli.

Kesinlikle üç veya daha fazla döngü seviyesine ihtiyaç duyan bazı şeyler var mı?

Algoritma bilge, muhtemelen, ancak yeterince etkileyici dillerde, kodu her zaman küçük parçalara (fonksiyonlar veya kapaklarla birlikte) yeniden aktarabilirsiniz.

Açıkçası, küçük yuvalama ve birbirlerini çağıran çok sayıda küçük işlev ile sözleşmelerini hecelemeden gizlenmiş bir kod yazabilirsiniz ...

... ancak, net sözleşmeli küçük fonksiyonların denetlenmesi, genel olarak net sözleşmeli büyük fonksiyonlardan çok daha kolaydır.


2
Bu resmi kılavuz olsa da, kılavuzun yürürlüğe girmediği çekirdek kodunda yer bulmak önemsizdir.
MikeB

1
@MikeB: Kuralları otomatik olarak uygulamak için tüm nedenler ...
Matthieu M.

1
@MatthieuM. Kurallar ve zorunlu gereklilikler arasındaki farkı anladığınızdan emin misiniz? Genel bir "temel kural" (eğer istersen bir rehber) olarak, kurallar daha çok tavsiye niteliğindedir ve uygulanmamaktadır.
Brendan,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.