(;;) veya while (doğru) için doğru C # sonsuz döngü hangisidir? [kapalı]


97

C / C ++ günlerime geri döndüğümde, "sonsuz döngü" olarak kodlama

while (true)

daha doğal hissettim ve bana göre daha açık göründü

for (;;)

1980'lerin sonunda PC-lint ile karşılaşma ve sonraki en iyi uygulamalar tartışmaları beni bu alışkanlıktan uzaklaştırdı. O zamandan beri forkontrol ifadesini kullanarak döngüleri kodladım . Bugün, uzun zamandır ilk kez ve belki de bir C # geliştiricisi olarak sonsuz döngüye ilk ihtiyacım, aynı durumla karşı karşıyayım. Biri doğru mu, diğeri değil mi?


5
İki dakikadan kısa sürede dört aynı cevap. Fena değil.
Jon B

5
Sonsuz döngünüzü açarak tüm dini tartışmalardan kaçınabilirsiniz. Uzun sürmez ...
Stephen Darlington

7
Sadece meraktan soruyorum: C / C ++ için (;;) için neden daha iyi?
Vilx

6
@Vilx hatırladığım kadarıyla eski derleyiciler for (;;) ile while (1) 'den daha verimli kod yazarlardı. İyi bir modern derleyicinin hemen hemen aynı kodu üreteceğinden eminim.
Stephen Darlington

4
Stephen ve Serhio'nun yorumlarına dayanarak: 1. while(true)Bir koşul gerektirir. for(;;)bu nedenle koşulsuz olarak tekrar eden sonsuz döngüler için daha iyi bir temsildir. 2. Optimize edilmeyen eski derleyiciler, döngü halini gerçekten değerlendirmiş olabilir (true). 3. C, teletipler, 300 baud terminalleri ve 1 karakterli değişken adlarından oluşan minimalist bir dildir. Her tuş vuruşunun önemli olduğu bir ortamda, for(;;)bundan biraz daha kısadır while(true).
Richard Dingwall

Yanıtlar:


124
while(true)
{

}

Her zaman kullandığım ve başkalarının manuel olarak kırılması gereken bir döngü için kullandığını gördüğüm şeydir.


@RSolberg - birbiri ardına saniyeler içinde sunulan iki benzer yanıt arasında bir tartışma oldu. Adam'ın takip eden yorumu, beni gelenekselden çok kullanıma dayalı bir cevabı kabul etmeye yöneltti.
Bob Kaufman

1
while ve for ikisi de elle kırılabilir
Allen Rice

2
Maalesef bu cevap soruyu cevaplamıyor. Doğru cevap "her ikisi de doğru" dur.
David R Tribble

2
@Loadmaster: Bu sizin "doğru" tanımınıza (veya daha doğrusu ne tür bir "doğruluk" peşinde olduğunuza) bağlıdır.
Adam Robinson

319

C # derleyicisi her ikisini de dönüştürecek

for(;;)
{
    // ...
}

ve

while (true)
{
    // ...
}

içine

{
    :label
    // ...
    goto label;
}

Her ikisi için CIL aynıdır. Çoğu insan while(true)okumayı ve anlamayı daha kolay bulur . for(;;)oldukça şifreli.

Kaynak:

.NET Reflector ile biraz daha uğraştım ve her iki döngüyü de Visual Studio'da "Optimize Code" ile derledim.

Her iki döngü de (.NET Reflector ile) derlenir:

Label_0000:
    goto Label_0000;

Raptorlar yakında saldırır.


7
evet, iki kez kontrol ettim, hepsi aynı IL kodu, bu kabul edilen cevap olmalı IMO :)
Allen Rice

64
Xkcd referansı için +1
Ikke

4
Bilgiçlik olmak gerekirse, derleyici yok değil diğer içine bir ifade biçimini dönüştürmek; daha ziyade, her iki ifade için aynı kodu üretir. Bu kod, gotoşaşırtıcı olmayan bir ifade olan btw ile aynıdır .
David R Tribble

1
ve sonra goto bir jmp talimatına çevrilir ..
Marco M.

25
açıkçası goto LOOPdoğru C # sonsuz döngü :)
Dustin Getz

61

Bunun okunmasının daha kolay olabileceğini ve kesinlikle C # 'da kullanım için standart olduğunu düşünüyorum:

while(true)
{
   //Do My Loop Stuff
}

19
@ voyager: 1, C # 'da' true 'yerine geçmez.
Adam Robinson

17
(1) geçersiz iken C #: Sabit 1
bool'a

4
while(1)a olmadığı için C # 'da geçerli 1değildir bool.
Pavel Minaev

48

Nefes al, kullan:

while (!false)
{

}

VEYA jsight'ın belirttiği gibi , iki kat emin olmak isteyebilirsiniz:

while (!false && true)
{
}

İnsanlar bana bağırmadan önce hepsi aynı CIL kodu, kontrol ettim :)


Şimdiye kadarki en iyi cevap.
Larry

38

Birkaç eski espriyi yeniden canlandırmak için:

  1. " for (;;) {}" Kullanmayın - ifadeyi ağlatır.
  2. Tabii sen " #define EVER ;;" olmadıkça .

25
Ya #define ever (;;)da bence daha okunaklı. for ever {}
Chris Lutz

1
C # 'da bir # tanım (;;) yapabileceğinizi düşünmemiştim ama şaka komik :)
Allen Rice

1
Ah. C'yi OS X'te programlıyorum. C # ön işlemcisinin bu kadar hadım edildiğini bilmiyordum. Bu soruyu okumaya başladım nasıl bile emin, ben ... bir ihmal etiketi olarak C # sahip değilim
Chris Lutz

C # önişlemcisi, en azından C, C ++, PL / 1 ve hatta makro derleyicilerin sağladığı gibi gerçekten bir ön işlemci değildir. Yalnızca önişlemci sembollerini tanımlayarak / tanımlayarak kod bloklarını etkinleştirmenize veya devre dışı bırakmanıza izin verir.
David R Tribble

6
Veya daha da iyisi #define forever while(true):;)
Roberto Bonvallet

26

Eski moda gitmek istiyorsanız, goto hala C # ile desteklenmektedir:

STARTOVER:  
    //Do something
    goto STARTOVER;

Gerçekten sonsuz bir döngü için, bu go-komutudur. =)



6
Bunu negatif bir derecelendirmeden sıfıra yükselttim, ancak yalnızca mizah değeri nedeniyle. Hey, tüm döngüler yine de JMP assembler işlem kodlarında derlenir, değil mi?
David R Tribble

@Loadmaster: Teşekkürler, onu başka bir seçenek olarak atıyordum, mutlaka onaylamıyorum.
JohnFx

2
@serhio: Daha da fazlası, bir yerde bir şeyler okuduğunuz için dil yapılarından kaçınmaktır. Hiçbir dil öğesi kendi başına kötü değildir, yalnızca kötü şekillerde kullanılabilir.
JohnFx

2
@serhio: Mümkün olan her anahtar kelimeyi kullanarak doğaya karşı iğrençlikler gördüm. Dil öğesi değil, programcıdır. Her halükarda, önceki yorumumda belirtildiği gibi, onu onaylamıyordum. Ben sadece onu bütünlük ve biraz mizah için ekledim.
JohnFx


10

Gerçek bir sonsuz döngüye ihtiyaç duyduğum durumlarda, her zaman kullandım

while(true) {...}

Niyeti ifade etmek için boş bir ifadeden daha iyi ifade ediyor gibi görünüyor.


10

Şahsen ben her zaman for(;;)tam olarak tercih ettim çünkü hiçbir koşulu yok ( while (true)her zaman doğru olanın aksine ). Bununla birlikte, bu gerçekten çok küçük bir stil noktası ve her iki şekilde de tartışmaya değeceğini düşünmüyorum. Her iki yaklaşımı da zorunlu kılan veya yasaklayan bir C # tarzı kılavuz görmedim.


derleyici dönüşümleri zaman, .NET değil değer yapmak senin (kötü okunabilir) için bir durum bulunmayan süre koşulu ile.
serhio

3
@serhio: Lütfen "derleyici dönüşümleri ... içinde" ile ne demek istediğinizi açıklayın while. Programcı söz konusu olduğunda, derleyici yüksek seviyeli kodu IL'ye dönüştürür. IL'de döngü while(veya for) yoktur , yalnızca etiketler ve gotoslar vardır.
Pavel Minaev

1
Pierre-Alain Vigeant'ın cevabına bakın.
serhio

3
Cevabı basitçe "derleyici her ikisi için de aynı IL'yi üretir" şeklinde daha iyi ifade edilebilir (AST düzeyinde herhangi bir şeyi dönüştürüp dönüştürmediğini ve ne zaman dönüştürdüğünü gerçekten bilemezsiniz ve bu her durumda bir uygulama ayrıntısıdır). Her durumda, bu neden ".NET'te buna değmediğini" açıklamıyor.
Aynısı

6

Ben şahsen for (;;)deyimi tercih ederim (C / C ++ açısından gelir). while (true)Bir anlamda daha okunabilir olduğunu kabul etmeme rağmen (ve C / C ++ 'da bile eskiden kullandığım şeydi), fordeyimi kullanmaya başladım çünkü:

  • Öne çıkıyor

Bir döngünün (normal bir şekilde) sona ermemesi gerçeğinin 'seslenmeye' değer olduğunu düşünüyorum ve bunu for (;;)biraz daha fazla yaptığını düşünüyorum.


son olarak, bunu kullanarak programların derlenmesini biraz daha bekleyeceğiz (dönüşümü for =>
while'dan derleyeceğiz

3
@serhio: Pek değil. Onu ' e dönüştürmez . Her ikisi için ve için yeni kod üretir . Bu cevaba bakın . forwhilefor (;;){}while (true){}while(true){}
wchargin

6

C # 'ın atalarının izini sürebileceği C için orijinal K&R kitabı önerilir

for (;;) ...

sonsuz döngüler için. Kesin, okunması kolay ve arkasında uzun ve asil bir geçmişi var.

Eklenti (Şub 2017)

Elbette, bu döngü formunun (veya başka herhangi bir formun) çok şifreli olduğunu düşünüyorsanız, her zaman sadece bir yorum ekleyebilirsiniz .

// Infinite loop
for (;;)
    ...

Veya:

for (;;)    // Loop forever
    ...

1
evet, ama bu C için, C # için değil.
serhio

1
C # ile çalışır. Ve C # dili C'den (dolaylı olarak) türetilmiştir.
David R Tribble

4
8 yıl sonra cevabınızı güncellemeye karar verdiniz. Nice
Metoniem

4

O olmalı while(true)değil while(1)bu yüzden, while(1)evet, C # yanlış;)


3

Alternatif olarak, sonsuz bir döngüye sahip olmanın normalde kötü bir uygulama olduğu söylenebilir, çünkü uygulama gerçekten sonsuza kadar çalışmadıkça bir çıkış durumuna ihtiyaç duyar. Ancak, eğer bu bir seyir füzesi içinse, açık bir çıkış koşulunun gerekli olmayabileceğini kabul edeceğim.

Bunu sevmeme rağmen:

for (float f = 16777216f; f < 16777217f; f++) { } 

2
-1: herkes kodu okurken "sonsuz
döngünüzü

C # ' f < 16777217fda her zaman false... yani bu asla döngü yapmaz.
NetMage

2

Biraz daha "okuryazar" kodu tercih ederim. Pratikte böyle bir şey yapma olasılığım çok daha yüksektir:

bool shouldContinue = true;
while (shouldContinue)
{
    // ...

    shouldContinue = CheckSomething();
}

1
Ugh. Aslında, bu do ... while()kılık değiştirmiş bir döngü. Bunu görmem birkaç saniyemi aldı. Bir do ... while()döngü yazmış olsaydın, hemen netleşirdi. -1
sbi

while (true) kullanabileceğiniz halde neden bir değişken bildirerek zaman ve kaynakları boşa harcayasınız? Bence mantıklı değil
waqasahmed

Bunu daha okunaklı buluyorum, özellikle belirli bir anlamlı bayrak ekleyebilirseniz, örneğin iptalin döngüyü durdurmanın tek yolu olduğunu belirtmek için "while (! This.canceled)", döngüyü belirtmek için "while (! ProcessExited)" Dışsal bir süreç ortadan kalkana kadar çalışmalıdır, vs. Sürdürülebilirlik veya okunabilirlik kolaylığı adına yapılması kesinlikle doğru olan "kaynakları boşa harcayan" pek çok şey vardır. "while (true)" o kadar da kötü değil, ama deneyimlerime göre genellikle daha iyi bir yol var.
bobbymcr

1
+1. Çoğu durumda, gerçek sonsuz döngü gerçekte olan şey değildir ve durmak isteyeceğiniz bir koşulunuz vardır (örneğin, yazıcı yandığında).
Lie Ryan

1
… Bu durumda kullanmalısınız break.
Ry-


1

Kod golfü yapıyorsanız, tavsiye ederim for(;;). Bunun ötesinde while(true), aynı anlama sahip ve daha sezgisel görünüyor. Her halükarda, çoğu kodlayıcı muhtemelen her iki varyasyonu da anlayacaktır, bu yüzden gerçekten önemli değil. En rahat olanı kullanın.


2
Eğer golf oynuyorsanız, C # zaten yanlış dildir.
SingleNegationElimination

1

while(true)Hangi dilde olursa olsun kod okunabilirliği açısından daha anlamlı olduğunu düşünüyorum. Bilgisayarın onu nasıl gördüğü açısından, günümüzün çok verimli derleyiciler ve yorumlayıcılardan oluşan toplumunda gerçekten bir fark olmamalı.

Herhangi bir performans farkı varsa, MSIL'e çevirinin optimize edeceğinden eminim. Gerçekten istersen, kontrol edebilirsin.


1

Söylememin tek nedeni for(;;)CodeDom sınırlamalarından kaynaklanıyor (döngüler CodeDom kullanılarak bildirilemez ve for döngüleri bir yineleme döngüsü olarak daha genel bir biçim olarak görülür).

Bu, fordöngü uygulamasının hem normal kod hem de CodeDom tarafından üretilen kod için kullanılabileceği gerçeği dışında bunu seçmek için oldukça gevşek bir nedendir . Yani daha standart olabilir.

Not olarak, bir whiledöngü oluşturmak için kod parçacıkları kullanabilirsiniz , ancak döngünün tamamının bir parçacık olması gerekir ...


1

Her ikisi de aynı işleve sahiptir, ancak insanlar genellikle tercih eder while(true). Okumak ve anlamak kolay geliyor ...


0

Her zaman true döndüren herhangi bir ifade while döngüsü için uygun olmalıdır.

Misal:

1==1 //Just an example for the text stated before 
true

Doğru da işe yararken neden onu 1 = 1 gibi bir karşılaştırma yapmaya zorlayasınız ki? Hesaplanmış bir ifade kullanmak, NUMBER_OF_ARMS = 598-3596 gibi bir sabiti tanımlamak kadar aptalca geliyor;
JohnFx

Koddan önce verilen cevaba bir örnek :)
George
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.