“While (true)” döngüleri çok mu kötü? [kapalı]


218

Birkaç yıldır Java'da program yapıyorum, ancak yakın zamanda resmi bir derece almak için okula döndüm. Son görevimde aşağıdaki gibi bir döngü kullandığım için puan kaybettiğimi öğrenmek beni oldukça şaşırttı.

do{
     //get some input.
     //if the input meets my conditions, break;
     //Otherwise ask again.
} while(true)

Şimdi testim için sadece bazı konsol girişleri için tarama yapıyorum, ancak bu tür bir döngünün cesaretinin kırıldığı söylendi, çünkü breakkullanım benzer goto, sadece yapmıyoruz.

gotoJava kuzeninin tuzaklarını ve tam anlamıyla anlıyorum ve break:labelonları kullanmamanın iyi bir anlamı var. Ayrıca, daha eksiksiz bir programın, örneğin programı sonlandırmak için başka bir kaçış yolu sağlayacağını da fark ettim, ancak bu, profesörümün belirttiği bir sebep değildi, bu yüzden ...

Sorun nedir do-while(true)?


23
Öğretmeninize bu tür şeylerin oldukça öznel olduğunu sorun.
Chris Eberle

18
Bu makalenin, goto hakkında neyin zararlı olduğunu anlamaya yardımcı olduğunu buldum . İle karşılaştırma breakmuhtemelen iyi anlamlıdır, ancak aslında yanlış anlaşılmıştır. Belki de profesörünüzü bu konuda eğitebilirsiniz;) Deneyimlerime göre profesörler programlama zanaat hakkında çok fazla şey bilmiyorlar.
Magnus Hoff

100
Bununla ilgili tek gerçekten tartışılmaz kötü şey aklımda, do {} while (true)eşdeğer while(true) {}ve ikincisi aslında daha geleneksel form ve çok daha net.
Voo

11
Eğer kimse basit ifade gücünü takdir etmezse break, onsuz bir dilde programlamayı denemelidir. Siz istemeden çok fazla döngü gerektirmez!
Steven

16
Ödev etiketine katılmıyorum.
aaaa bbbb

Yanıtlar:


220

Söylemem Kötü - ama aynı şekilde normalde en azından bir alternatif ararım.

Yazdığım ilk şeyin olduğu durumlarda, neredeyse her zaman en azından onu daha net bir şeye dönüştürmeye çalışırım . Bazen yardım edilemez (ya da alternatif birbool döngünün sonunu belirtmek dışında anlamlı olmayan hiçbir şey yapmayan değişkene sahip bir breakifadeden daha az açıktır ) ama en azından denemeye değer.

breakBir bayraktan daha açık nerede kullanıldığına bir örnek olarak şunları göz önünde bulundurun:

while (true)
{
    doStuffNeededAtStartOfLoop();
    int input = getSomeInput();
    if (testCondition(input))
    {
        break;
    }
    actOnInput(input);
}

Şimdi bir bayrak kullanmaya zorlayalım:

boolean running = true;
while (running)
{
    doStuffNeededAtStartOfLoop();
    int input = getSomeInput();
    if (testCondition(input))
    {
        running = false;
    }
    else
    {
        actOnInput(input);
    }
}

İkincisini okumak için daha karmaşık olarak görüyorum: ekstra bir elsebloğu var actOnInput, daha girintili ve eğer testConditiongeri döndüğünde ne olacağını bulmaya çalışıyorsanız true, orada kontrol etmek için bloğun geri kalanına dikkatlice bakmanız gerekir. bir şey değil sonraelse mı oluşacak bloğuna runningolarak ayarlandı falseya da değil.

breakİfadesi daha net niyet iletişim kurar ve bloğun geri kalanı daha önce koşulları hakkında endişelenmeden yapması gereken yapmalarına olanak tanır.

Bunun, insanların bir yöntemde birden çok döndürme ifadesine sahip olduğu gibi aynı argüman olduğunu unutmayın. Örneğin, ilk birkaç satırdaki bir yöntemin sonucunu çözebilirsem (örneğin, bazı girdiler boş, boş veya sıfır olduğu için), bu yanıtı doğrudan sonucu depolamak için bir değişkene sahip olmaktan daha açık bir şekilde döndürürüm , daha sonra başka bir kod bloğu ve son olarak bir returnifade.


3
Katıldığım ilk araç olmadığına katılıyorum, ama sadece sorunu çok temiz bir şekilde hallediyor gibiydi ve temiz kodu sevdim.
JHarnach

3
@ X-Zero: Evet, bazen. Eğer "mola" sık sık "iyilik" dönüştürebilirsiniz ... yine de bir sonunda olabilirwhile (true)
Jon Skeet

21
@trutheality: Kodumun çoğunun olabildiğince girintisiz olmasını tercih ediyorum. Ve bileşik bir ödevi olan bir durum benim için daha karmaşık geliyor.
Jon Skeet

3
@Vince: Evet, ve durumu döngü başlangıcında kolayca ifade edebiliyorsanız bu harika . Ama bazen yapamazsınız - ve bahsettiğimiz durum budur. Lütfen cevabımın ilk birkaç cümlesine dikkat edin.
Jon Skeet

6
@Ismail: Umarım değil. Yayınlar, yazarın değil, yalnızca içeriklerine göre değerlendirilmelidir. Heck, bir Eric Lippert gönderisini bile yanlış / yardımcı olmadığını hissettim. Bu henüz olmadı :)
Jon Skeet

100

AFAIK hiçbir şey, gerçekten. Öğretmenler alerjisi var goto, çünkü bir yerde gerçekten kötü olduğunu duydular. Aksi takdirde şunu yazarsınız:

bool guard = true;
do
{
   getInput();
   if (something)
     guard = false;
} while (guard)

Bu neredeyse aynı şey.

Belki bu daha temizdir (çünkü tüm döngü bilgileri bloğun üstünde bulunur):

for (bool endLoop = false; !endLoop;)
{

}

4
Sona erdirme koşulu çok daha görünür olduğu için önerilerinizi beğeniyorum. Bu, kodu okurken daha önce ne yapmaya çalıştığını anlayacaksınız demektir. Sonsuz bir döngü kullanmam ama iki sürümünüzü sık sık kullanmam.
Kızak

4
Oybirliği, bir bayrağın niyetini ifade ettiği için büyük ölçüde kırılmasından daha iyi olduğudur. Bunun faydalı olduğunu görebiliyorum. Bütün katı cevaplar, ama bunu kabul edilmiş olarak işaretleyeceğim.
JHarnach

20
Bunların her ikisi de, kırıldığınızı bilseniz bile , halkanın geri kalanının (en azından bazı durumlarda) en azından döngü gövdesinin sonuna gitmeye devam ederek kirlenmesinden muzdariptir . Cevabımda bir örnek vereceğim ...
Jon Skeet

8
Jon Skeet'in cevabını daha iyi seviyorum. Ayrıca, (true) {}, {} yapmaktan çok daha iyi iken (true)
aaaa bbbb

1
Dijkstra'nın GoTo makalesini yazmasından nefret ediyorum. GoTo kesinlikle geçmişte sık sık istismar edildi olsa da, asla kullanmamalısınız anlamına gelmez. Ayrıca, Exit For, Break, Exit While, Try / Catch sadece Goto'nun özel biçimleridir. Gotos genellikle kodu daha okunabilir hale getirebilir. Ve evet, Goto olmadan her şeyin yapılabileceğinin farkındayım. Bu olması gerektiği anlamına gelmez.
Kibbee

39

Douglas Crockford, JavaScript'in nasıl bir loopyapı içermesini istediğine dair bir açıklama yaptı :

loop
{
  ...code...
}

Ve sanmıyorum Java a sahip herhangi kötü olurduloop yapıya .

İle doğal olarak yanlış bir şey yok while(true)döngüler, ama orada olduğunu , onları vazgeçirmek için öğretmenler için bir eğilim. Öğretme perspektifinden bakıldığında, öğrencilerin sonsuz döngüler oluşturmaları ve döngünün neden hiç kaçmadığını anlamaması çok kolaydır.

Ancak nadiren bahsettikleri, tüm döngü mekanizmalarının while(true)döngülerle çoğaltılabileceğidir .

while( a() )
{
  fn();
}

aynıdır

loop
{
  if ( !a() ) break;
  fn();
}

ve

do
{
  fn();
} while( a() );

aynıdır:

loop
{
  fn();
  if ( !a() ) break;
}

ve

for ( a(); b(); c() )
{
  fn();
}

aynıdır:

a();
loop
{
  if ( !b() ) break;
  fn();
  c();
}

Döngülerinizi kullanmayı seçtiğiniz yapıda çalışacak şekilde ayarlayabildiğiniz sürece önemsizdir. O Eğer olur bir sığacak şekilde fordöngü, bir kullanmak fordöngü.

Son bir bölüm: döngülerinizi basit tutun. Her yinelemede olması gereken çok fazla işlevsellik varsa, onu bir işleve yerleştirin. Çalıştırdıktan sonra her zaman optimize edebilirsiniz.


2
+1: İfadeler söz konusu forolduğunda döngülerle ilgili ek karmaşıklıklar continuevardır, ancak bunlar büyük bir uzantı değildir.
Donal Fellows

Karşılaşmak istediğim bir dizi olduğunda genellikle for döngüsü, tanışmak istediğim bir durum olduğunda ise while döngüsü kullanıyorum. Bu, kodu daha okunaklı imo tutar.
dascandy

4
Artık kimse yazmıyor for (;;) {mu? ("Sonsuza dek" telaffuz edilir). Bu eskiden çok popülerdi.
Dawood ibn Kareem

16

1967'de Edgar Dijkstra, bir ticaret dergisinde kod kalitesini artırmak için neden üst düzey dillerden kaldırılması gerektiğine dair bir makale yazdı. "Yapısal programlama" adı verilen bir programlama paradigması ortaya çıktı, ancak kesinlikle herkes otomatik olarak kötü kod anlamına geldiğini kabul etmiyor.

Yapısal programlamanın özü, esasen kodun yapısının, gitmesi veya kırılması yerine akışını belirlemesi veya mümkün olan yerlerde akışı belirlemeye devam etmesidir. Aynı şekilde, bir döngü veya işleve birden çok giriş ve çıkış noktası olması da bu paradigmada önerilmez.

Açıkçası bu tek programlama paradigması değildir, ancak genellikle nesne yönelimli programlama (ala Java) gibi diğer paradigmalara da kolayca uygulanabilir.

Öğretmenleriniz muhtemelen öğretilmiştir ve sınıfınıza, kodumuzun yapılandırıldığından emin olarak ve yapılandırılmış programlama kurallarını izleyerek "spagetti kodundan" en iyi kaçınacağımızı öğretmeye çalışmaktadır.

Break kullanan bir uygulamada doğal olarak "yanlış" bir şey olmasa da, bazıları, while () koşulu içinde loop koşulunun açıkça belirtildiği ve aşırı derecede zor olma olasılıklarını ortadan kaldırdığı kodun okunmasını önemli ölçüde kolaylaştırır. Yanlışlıkla sonsuz bir döngü oluşturma veya okunması zor veya gereksiz bir şekilde kafa karıştırıcı kod yapma riski gibi acemi programcılar tarafından kodda sıkça ortaya çıkan bir süre (gerçek) koşulu kullanmanın kesinlikle tuzakları vardır.

İronik olarak, istisna işleme, yapılandırılmış programlamadan sapmanın kesinlikle ortaya çıkacağı ve Java'da programlamaya daha fazla girdiğinizde beklenen bir alandır.

Eğitmeniniz, metninizin o bölümünde veya dersinde öğretilen belirli bir döngü yapısını veya sözdizimini kullanma yeteneğinizi göstermenizi beklemiş olabilir ve yazdığınız kod işlevsel olarak eşdeğer olsa da, o derste öğrenmeniz gerekiyordu.


2
İşte Edsger Dijkstra'nın makalesi . İyi bir okuma.
Roy Prins

14

Girişi okumak için olağan Java kuralı:

import java.io.*;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String strLine;

while ((strLine = br.readLine()) != null) {
  // do something with the line
}

Ve girişi okumak için her zamanki C ++ kuralı:

#include <iostream>
#include <string>
std::string data;
while(std::readline(std::cin, data)) {
  // do something with the line
}

Ve C de,

#include <stdio.h>
char* buffer = NULL;
size_t buffer_size;
size_t size_read;
while( (size_read = getline(&buffer, &buffer_size, stdin)) != -1 ){
  // do something with the line
}
free(buffer);

veya dosyanızdaki en uzun metin satırının ne kadar uzun olduğunu bildiğinize ikna olduysanız,

#include <stdio.h>
char buffer[BUF_SIZE];
while (fgets(buffer, BUF_SIZE, stdin)) {
  //do something with the line
}

Kullanıcının bir quitkomut girip girmediğini test ediyorsanız , bu 3 döngü yapısından herhangi birini genişletmek kolaydır. Bunu sizin için Java'da yapacağım:

import java.io.*;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;

while ((line = br.readLine()) != null  && !line.equals("quit") ) {
  // do something with the line
}

Bu nedenle, kesinlikle breakveya gotohaklı olduğu durumlar olsa da , yaptığınız tek şey bir dosyadan veya konsoldan satır satır while (true)okumaksa, bunu gerçekleştirmek için bir döngüye ihtiyacınız olmamalıdır - programlama diliniz zaten size loop koşul olarak input komutunu kullanmak için uygun bir deyim ile.


Aslında, while (true)bu geleneksel giriş döngülerinden biri yerine bir döngü kullanıyorsanız , dosyanın sonunu kontrol etmeyi unutabilirsiniz.
Ken Bloom

3
Bunu, döngünün ilk bölümünü whilekoşullu olarak doldurarak etkili bir şekilde başarıyorsunuz . Son Java koşulunda zaten oldukça ağırlaşıyor ve devam edip etmemeye karar vermek için kapsamlı manipülasyon yapmanız gerekiyorsa, oldukça uzun sürebilir. Ayrı bir işleve ayırabilirsiniz ve bu en iyisi olabilir. Ancak bir işlevde olmasını istiyorsanız ve devam edip etmeyeceğinize karar vermeden önce yapılması gereken önemsiz bir iş varsa, en while(true)iyisi olabilir.
poolie

@poolie: O zaman muhtemelen read komutunu loop koşulu (EOF için kontrol eder) olarak kullanmak ve loop içindeki diğer koşullarınızı break ifadeleri olarak kontrol etmek en iyisidir.
Ken Bloom

1
Değeri için gets()ortak bir sözleşme değil. Taşmaları tamponlamak için oldukça elverişlidir. fgets(buffer, BUFFER_SIZE, file)standart uygulamaya çok benzer.
Dave

@Dave: Şimdi kullanmak için cevabı düzenledim fgets.
Ken Bloom

12

Bu korkunç bir şey değil, ancak kodlarken diğer geliştiricileri de dikkate almanız gerekiyor. Okulda bile.

Geliştiricileriniz, döngü bildiriminde döngü için çıkış yan tümcesini görebilmelidir. Bunu sen yapmadın. Çıkış yan tümcesini döngünün ortasına sakladınız ve birlikte gelen ve kodunuzu anlamaya çalışan biri için daha fazla iş yaptınız. Bu "mola" gibi şeylerden kaçınılmasıyla aynı nedendir.

Bununla birlikte, gerçek dünyada hala bir sürü kodda böyle şeyler göreceksiniz.


4
Döngü ile başlarsa , içinde veya içinde olacağı veya sonsuza kadar çalışacağı while (true)oldukça açıktır . Basit olmak önemlidir, ancak özellikle kötü değildir. Döngü yinelemelerinde karmaşık değişmezleri olan değişkenler, çok daha öfkeye neden olan bir şeye örnek olacaktır. breakreturnwhile(true)
poolie

4
Bir aramada üç seviye derine inmeyi ve sonra bir şekilde ayrılmayı deneyin. Bu noktadan sonra geri dönmezseniz kod çok daha kötü olacaktır.
dascandy

11

Bu senin silahın, mermin ve ayağın ...

Kötü çünkü sorun istiyorsun. Siz veya bu sayfadaki kısa / basit hal döngüleri örnekleri olan diğer posterlerden herhangi biri olmayacak.

Sorun gelecekte çok rastgele bir zamanda başlayacak. Başka bir programcıdan kaynaklanıyor olabilir. Yazılımı yükleyen kişi olabilir. Son kullanıcı olabilir.

Neden? Bir 700K LOC uygulamasının neden her CPU dolana kadar CPU zamanının% 100'ünü yavaş yavaş yakmaya başlayacağını bulmak zorundaydım. Bu inanılmaz bir (gerçek) döngü oldu. Büyük ve iğrençti ama aşağıya kaynatıldı:

x = read_value_from_database()
while (true) 
 if (x == 1)
  ...
  break;
 else if (x ==2)
  ...
  break;
and lots more else if conditions
}

Başka bir son şube yoktu. Değer bir if koşuluyla eşleşmezse, döngü zaman sonuna kadar çalışmaya devam etti.

Tabii ki, programcı son kullanıcıları programcının beklediği bir değer seçmedikleri için suçladı. (Daha sonra koddaki while (true) tüm örneklerini kaldırdım.)

IMHO while (true) gibi yapıları kullanmak iyi bir savunma programı değildir. Size musallat olmak için geri gelecek.

(Ama i ++ için bile her satıra yorum yapmadıysak not verdim profesörleri hatırlıyorum;)


3
Savunma programlama hakkında yorum için +1.
JHarnach

3
Örneğinizde, kod while (true) seçimi nedeniyle değil, kodun etrafına bir döngü koyma fikri nedeniyle aptalca.
Florian F

Gerçekten, bu döngünün amacı neydi? :)
juzzlin

6

Yapısal programlama yapılarının (biraz yapılandırılmamış) kesme ve devam etme ifadelerine tercih edilmesi anlamında kötüdür. Karşılaştırma yapılarak, bu prensibe göre "goto" ya tercih edilirler.

Kodunuzu her zaman mümkün olduğunca yapılandırılmış hale getirmenizi öneririm ... Jon Skeet'in de belirttiği gibi, kodunuzu bundan daha yapılandırılmış yapmayın!


5

Deneyimlerime göre çoğu durumda döngüler devam etmek için "ana" koşula sahiptir. Bu while () operatörünün kendisine yazılması gereken durumdur. Döngüyü kırabilecek tüm diğer koşullar ikincil, çok önemli değil vb. Bunlar ek if() {break}ifadeler olarak yazılabilir .

while(true) genellikle kafa karıştırıcıdır ve daha az okunabilir.

Bu kuralların vakaların% 100'ünü değil, muhtemelen sadece% 98'ini kapsadığını düşünüyorum.


İyi dedi. Şununla bir for for döngüsü yapmak gibidir: while (true) {i ++; ...}. Döngü koşulunu 'imza' yerine döngü içine gömüyorsunuz.
LegendLength

3

Neden kullanılmamaya ilişkin bir cevap olmasa da while (true), her zaman bu komik ve eşlik eden yazarın ifadesini buldum yapmak yerine neden yapılması gerektiğine dair kısa ve öz bir açıklama .

Sorunuzla ilgili olarak: ile ilgili doğal bir sorun yoktur.

while(true) {
   do_stuff();
   if(exit_time) {
      break;
   }
}

... ne yaptığınızı biliyorsanız ve bir exit_timenoktada bununtrue .

Öğretmenler sizi kullanmaktan caydırır, while(true)çünkü ne yaptığınızı tam olarak bildiğiniz noktaya gelene kadar kritik bir hata yapmanın kolay bir yoludur.


Bence ayar exit_time = false; while(!exit_time) { execute_stuff(); }ve do { execute_stuff(); } while(! exit_time );her ikisi de çok daha açık if( condition ) { break; }olan bir döngü sonunda bir while(true). Kopmalar döngülere kısa devrelerdir - bir döngünün ortasında kısa devre olarak kullanıldığında mükemmel para cezası vardır, ancak while deyimindeki bir koşulu, bir döngünün sonunda kesilmeye karşı bir durumu değerlendirmelisiniz.
dr jimbob

Bu çizgi romanla ilgili olarak: do-while yapabildiği her şeyi yapamazken, do-while bazen bunu yaparken yapabileceği şeyleri yapmak daha iyidir.
Theraot

3

While döngüsünün ne zaman sonlandırılacağını belirtmek için bir Boole bayrağı kullanabilirsiniz. Breakvego to yazılımın bakımı zor olmak için nedenlerdi - yazılım krizi (tm) - ve bundan kaçınılmalıdır ve kolayca da olabilir.

Eğer pragmatik ya da değil bir soru. Pragmatik kodlayıcılar bu basit durumda mola kullanabilirler.

Ancak bunları kullanmama alışkanlığını elde etmek iyidir, aksi takdirde bunları, kodunuzun okunabilirliğinin ve sürdürülebilirliğinin zorlaştığı karmaşık iç içe döngülerde olduğu gibi, uygun olmayan durumlarda alışkanlık dışında kullanabilirsiniz break.


8
Boole bayrağı tutmak muhtemelen daha net değildir ve daha az net olabilir, benim deneyimime göre?
Jon Skeet

3
@Jon Skeet Peki, iyi bir alışkanlıkla devam etmek ya da mola kullanarak kendinizi kötü bir alıştırma yapmak. "Koşu" adlı bir bool sizin için net değil mi? Onun açık, hata ayıklamak kolay ve daha önce de belirttiğim gibi iyi bir alışkanlık tutmak için iyi bir şey. Sorun nerede?
Daniel Leschkowski

4
Daha sonra if (running)tüm istediğim döngü çıkmak için zaman kodun geri kalanını girintili bir döngü içinde olmasını gerektirir çalışan denilen bir bool benim için tam olarak ne istediğini belirten basit bir break deyiminden daha az açıktır . Break'i aksiyomatik olarak kötü bir alışkanlık olarak kullanmayı düşünüyorsunuz - ben öyle düşünmüyorum.
Jon Skeet

2
Neden döngü içinde bir if (çalışıyor) var? Döngünün sonunda molada olduğu gibi, mola kullanmak yerine bayrağını kırmak ve çevirmek isteyip istemediğinizi kontrol edin ve flag'i (true) yerine while (çalışıyor) olarak kullanın. Ne demek istediğini anlamıyorum. Pragmatik bir kodlayıcının belirli durumlarda mola kullanabileceğini kabul ediyorum, ama gerçekten benim önerim altında yaptığınız yorumları alamıyorum
Daniel Leschkowski

3
Bırakıp bırakmamaya karar verdikten sonra döngü içinde herhangi bir şey yapmanız gerekmediğini varsayıyorsunuz. Örneğin, OP'nin durumunda, bırakmıyorsa daha fazla girdi istemesi gerekir.
Jon Skeet

3

Belki şanssızım. Ya da belki de bir deneyimim yok. Ama başa hatırlıyorum her zaman while(true)sahip breakiçeride, uygulamadan kodu geliştirmek mümkün oldu Özü Yöntemi için ise blok tuttu, while(true)bütün dönüştürülmüş ancak (tesadüfen?) breakİçine ler returns.

Deneyimlerime göre ara while(true)vermeden (yani geri dönüşler veya atışlarla) oldukça rahat ve anlaşılması kolaydır.


  void handleInput() {
      while (true) {
          final Input input = getSomeInput();
          if (input == null) {
              throw new BadInputException("can't handle null input");
          }
          if (input.isPoisonPill()) {
              return;
          }
          doSomething(input);
      }
  }

3

Bence evet oldukça kötü ... ya da en azından birçok geliştirici için. Döngü koşullarını düşünmeyen geliştiricilerin semptomatiktir. Sonuç olarak hata eğilimli olur.


2

İle hiçbir önemli sorun var while(true)olanbreak tablolar, ancak bazı onun biraz kod okunabilirliği azaltır düşünebilir. Değişkenlere anlamlı adlar vermeye çalışın, ifadeleri uygun yerde değerlendirin.

Örneğin, şöyle bir şey yapmak çok daha net görünüyor:

do {
   input = get_input();
   valid = check_input_validity(input);    
} while(! valid)

Bu, while döngüsü uzun sürerse özellikle doğrudur - ek bir yinelemenin olup olmadığını görmek için denetimin tam olarak nerede olduğunu bilirsiniz. Tüm değişkenler / işlevler soyutlama düzeyinde uygun isimlere sahiptir. while(true)Açıklamada, işleme, düşünce yerinde olmadığı söylemek etmez.

Belki döngüden ikinci kez farklı çıktılar istersiniz. Gibi bir şey

input = get_input();
while(input_is_not_valid(input)) {
    disp_msg_invalid_input();
    input = get_input();
}

o zaman bana daha okunabilir görünüyor

do {
    input = get_input();
    if (input_is_valid(input)) {
        break;
    }
    disp_msg_invalid_input();
} while(true);

Yine, önemsiz bir örnekle her ikisi de oldukça okunabilir; ancak döngü çok büyük veya derin yuvalanmışsa (muhtemelen zaten yeniden düzenlenmiş olmanız gerektiği anlamına gelir), ilk stil biraz daha net olabilir.


1

Birçok fonksiyonumda benzer bir şey kullanıyorum, fakat karşıt mantıkla.

DWORD dwError = ERROR_SUCCESS;

do
{
    if ( (dwError = SomeFunction()) != ERROR_SUCCESS )
    {
         /* handle error */
         continue;
    }

    if ( (dwError = SomeOtherFunction()) != ERROR_SUCCESS )
    {
         /* handle error */
         continue;
    }
}
while ( 0 );

if ( dwError != ERROR_SUCCESS )
{
    /* resource cleanup */
}

1

Bu daha çok estetik bir şeydir, döngüyü neden döngü bildiriminde durduracağını açıkça bildiğiniz kodu okumak çok daha kolaydır .


1

Genel olarak iyi bir fikir olarak görülmemesinin nedeninin, yapıyı tam potansiyeline kullanmamanız olduğunu söyleyebilirim. Ayrıca, birçok programlama eğitmeninin öğrencileri "bagaj" ile geldiklerinde bundan hoşlanmadığını düşünüyorum. Demek istediğim, öğrencilerin programlama tarzı üzerinde birincil etki olmayı severler. Belki de bu sadece eğitmenlerin evcil hayvanı.


1

Bana göre sorun okunabilirlik.

Gerçek koşullu bir while ifadesi döngü hakkında hiçbir şey söylemez. Anlama işini çok daha zorlaştırır.

Bu iki parçacıktan anlaşılması daha kolay ne olabilir?

do {
  // Imagine a nice chunk of code here
} while(true);

do {
  // Imagine a nice chunk of code here
} while(price < priceAllowedForDiscount);

0

Sanırım öğretmeninize mola vermek, meyveyi almak için bir ağaç dalını kırmak, diğer hileleri kullanmak (dalı yay) gibi olur, böylece meyveyi alırsınız ve dal hala canlıdır. :)


0

1) Hiçbir şey yanlış do -while(true)

2) Öğretmeniniz yanlış.

NSFs !!:

3) Çoğu öğretmen programcı değil öğretmendir.


@Connell öğretmeni duyuncaya kadar bekle!
Pacerier

1
Kendimi programlama cephesinde öğrettim. Aradığım tek şey, her şeyi kesinlikle konumlandırılmış bir bölüm olacak şekilde Dreamweaver'ı kullanarak web siteleri yapmayı öğreten ortaokuldaki BT öğretmenim ...
Connell

@ Sözleşmenizi göstermek için mesajımı kaldırın
Pacerier

2
"Yapamayanlar, öğretin." - Bu oldukça büyük bir genelleme değil mi? Eğitmenleri size göre yetersiz olduğu için doktorlar, mühendisler, pilotlar vb. Kendi kendine öğretilmeli mi?
filip-fku

@ filip-fku vay vay ~ soğut onu serin!
Pacerier

0

Döngünüzün bir arka plan iş parçacığı üzerinde çalışması kötü olabilir, bu nedenle bir UI iş parçacığını sonlandırarak uygulamanızı kapattığınızda, bu kod parçası yürütülmeye devam eder. Diğerlerinin söylediği gibi, iptal için bir yol sağlamak için her zaman bir tür kontrol kullanmalısınız.

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.