Ich programmiere seit einigen Jahren in Java, bin aber erst kürzlich zur Schule zurückgekehrt, um einen formalen Abschluss zu machen. Ich war ziemlich überrascht zu erfahren, dass ich bei meiner letzten Aufgabe Punkte verloren habe, weil ich eine Schleife wie die folgende verwendet habe.
do{
//get some input.
//if the input meets my conditions, break;
//Otherwise ask again.
} while(true)
Für meinen Test suche ich nur nach Konsoleneingaben, aber mir wurde gesagt, dass von dieser Art von Schleife abgeraten wird, da die Verwendung break
ähnlich ist goto
, wir tun es einfach nicht.
Ich verstehe die Fallstricke goto
und seinen Java-Cousin voll und ganz break:label
und habe den guten Sinn, sie nicht zu benutzen. Mir ist auch klar, dass ein vollständigeres Programm ein anderes Mittel zur Flucht bieten würde, zum Beispiel um das Programm zu beenden, aber das war kein Grund, den mein Professor angeführt hat, also ...
Was ist los mit do-while(true)
?
quelle
break
ist wahrscheinlich gut gemeint, wird aber tatsächlich missverstanden. Vielleicht können Sie Ihren Professor darüber unterrichten;) Nach meiner Erfahrung wissen Professoren nicht viel über das Handwerk des Programmierens.do {} while (true)
äquivalent zuwhile(true) {}
und letztere bei weitem die konventionellere Form und viel klarer ist.break
, sollte er versuchen, in einer Sprache ohne sie zu programmieren. Es dauert nicht zu viele Schleifen, bis Sie es wünschen!Antworten:
Ich würde nicht sagen, dass es schlecht ist - aber genauso würde ich normalerweise zumindest nach einer Alternative suchen.
In Situationen, in denen es das erste ist, was ich schreibe, versuche ich fast immer, es zumindest in etwas Klareres umzugestalten. Manchmal kann nicht geholfen werden (oder die Alternative besteht darin, eine
bool
Variable zu haben , die nichts Sinnvolles tut, als das Ende der Schleife anzugeben, weniger klar als einebreak
Anweisung), aber es lohnt sich zumindest, es zu versuchen.break
Betrachten Sie als Beispiel dafür, wo die Verwendung klarer ist als eine Flagge:Jetzt zwingen wir es, eine Flagge zu verwenden:
Ich halte letzteres für komplizierter zu lesen: Es hat einen zusätzlichen
else
Block, deractOnInput
ist stärker eingerückt, und wenn Sie herausfinden möchten, was bei dertestCondition
Rückgabe passierttrue
, müssen Sie den Rest des Blocks sorgfältig durchsehen, um dies dort zu überprüfen ist nicht etwas nach demelse
Block, das auftreten würde, obrunning
gesetzt wurdefalse
oder nicht.Die
break
Anweisung kommuniziert die Absicht klarer und lässt den Rest des Blocks mit dem fortfahren, was er tun muss, ohne sich um frühere Bedingungen sorgen zu müssen.Beachten Sie, dass dies genau das gleiche Argument ist, das Benutzer für mehrere return-Anweisungen in einer Methode haben. Wenn ich beispielsweise das Ergebnis einer Methode in den ersten Zeilen berechnen kann (z. B. weil eine Eingabe null oder leer oder null ist), finde ich es klarer, diese Antwort direkt zurückzugeben, als eine Variable zum Speichern des Ergebnisses zu haben , dann ein ganzer Block anderen Codes und schließlich eine
return
Anweisung.quelle
while (true)
AFAIK eigentlich nichts. Lehrer sind nur allergisch gegen
goto
, weil sie irgendwo gehört haben, dass es wirklich schlimm ist. Sonst würdest du einfach schreiben:Welches ist fast das gleiche.
Vielleicht ist dies sauberer (weil alle Schleifeninformationen oben im Block enthalten sind):
quelle
Douglas Crockford hatte eine Bemerkung darüber, wie er wünschte, JavaScript würde eine
loop
Struktur enthalten:Und ich denke nicht, dass Java schlechter wäre, wenn man ein
loop
Struktur .An
while(true)
Schleifen ist an sich nichts auszusetzen , aber es gibt sie eine Tendenz für die Lehrer , sie zu entmutigen. Aus der Sicht des Unterrichts ist es sehr einfach, dass Schüler Endlosschleifen erstellen und nicht verstehen, warum die Schleife nie entkommen wird.Was sie jedoch selten erwähnen, ist, dass alle Schleifenmechanismen mit repliziert werden können
while(true)
Schleifen werden können.ist das gleiche wie
und
ist das gleiche wie:
und
ist das gleiche wie:
Solange Sie Ihre Schleifen so einrichten können, dass sie funktionieren, ist das von Ihnen ausgewählte Konstrukt unwichtig. Wenn es passiert , in einer passen
for
Schleife, verwenden Sie einfor
Schleife.Ein letzter Teil: Halten Sie Ihre Loops einfach. Wenn bei jeder Iteration viele Funktionen erforderlich sind, fügen Sie diese in eine Funktion ein. Sie können es jederzeit optimieren, nachdem es funktioniert hat.
quelle
for
Schleifen, wenncontinue
Anweisungen beteiligt sind, aber sie sind keine wesentliche Erweiterung.for (;;) {
mehr? (Ausgesprochen "für immer"). Dies war früher sehr beliebt.Bereits 1967 schrieb Edgar Dijkstra in einem Fachmagazin einen Artikel darüber, warum goto aus Hochsprachen entfernt werden sollte, um die Codequalität zu verbessern. Daraus entstand ein ganzes Programmierparadigma namens "strukturierte Programmierung", obwohl sicherlich nicht alle zustimmen, dass goto automatisch schlechten Code bedeutet.
Der Kern der strukturierten Programmierung besteht im Wesentlichen darin, dass die Struktur des Codes seinen Fluss bestimmen sollte, anstatt Gotos oder Unterbrechungen zu haben, oder den Fluss weiterhin bestimmt, wo immer dies möglich ist. In ähnlicher Weise wird in diesem Paradigma auch davon abgeraten, mehrere Eintritts- und Austrittspunkte zu einer Schleife oder Funktion zu haben.
Offensichtlich ist dies nicht das einzige Programmierparadigma, aber oft kann es leicht auf andere Paradigmen wie die objektorientierte Programmierung (ala Java) angewendet werden.
Ihre Lehrer wurden wahrscheinlich unterrichtet und versuchen, Ihrer Klasse beizubringen, dass wir "Spaghetti-Code" am besten vermeiden, indem wir sicherstellen, dass unser Code strukturiert ist und die implizierten Regeln der strukturierten Programmierung befolgen.
Während bei einer Implementierung, die break verwendet, nichts von Natur aus "falsch" ist, halten es einige für wesentlich einfacher, Code zu lesen, bei dem die Bedingung für die Schleife explizit in der while () - Bedingung angegeben ist, und eliminieren einige Möglichkeiten, übermäßig knifflig zu sein. Es gibt definitiv Fallstricke bei der Verwendung einer (wahren) while-Bedingung, die von unerfahrenen Programmierern häufig im Code auftaucht, z. B. das Risiko, versehentlich eine Endlosschleife zu erstellen oder Code zu erstellen, der schwer zu lesen oder unnötig verwirrend ist.
Ironischerweise ist die Ausnahmebehandlung ein Bereich, in dem Abweichungen von der strukturierten Programmierung sicherlich auftreten und zu erwarten sind, wenn Sie weiter in die Programmierung in Java einsteigen.
Es ist auch möglich, dass Ihr Kursleiter von Ihnen erwartet hat, dass Sie nachweisen, dass Sie in der Lage sind, eine bestimmte Schleifenstruktur oder Syntax zu verwenden, die in diesem Kapitel oder in dieser Lektion Ihres Textes vermittelt wird, und obwohl der von Ihnen geschriebene Code funktional äquivalent ist, haben Sie dies möglicherweise nicht demonstriert besondere Fähigkeit, die Sie in dieser Lektion lernen sollten.
quelle
Die übliche Java-Konvention zum Lesen von Eingaben lautet:
Und die übliche C ++ - Konvention zum Lesen von Eingaben lautet:
Und in C ist es
oder wenn Sie überzeugt sind, dass Sie wissen, wie lang die längste Textzeile in Ihrer Datei ist, können Sie dies tun
Wenn Sie testen, ob Ihr Benutzer einen
quit
Befehl eingegeben hat , können Sie diese drei Schleifenstrukturen problemlos erweitern. Ich mache es in Java für Sie:Während es sicherlich Fälle gibt, in denen dies gerechtfertigt ist
break
odergoto
gerechtfertigt ist, sollten Sie, wenn Sie nur Zeile für Zeile aus einer Datei oder der Konsole lesen, keinewhile (true)
Schleife benötigen , um dies zu erreichen - Ihre Programmiersprache hat Sie bereits versorgt mit einer geeigneten Redewendung für die Verwendung des Eingabebefehls als Schleifenbedingung.quelle
while (true)
anstelle einer dieser herkömmlichen Eingabeschleifen eine Schleife verwenden, vergessen Sie möglicherweise, nach dem Ende der Datei zu suchen.while
Bedingung einfügen. In der endgültigen Java-Bedingung wird es bereits ziemlich heftig, und wenn Sie umfangreiche Manipulationen vornehmen müssen, um zu entscheiden, ob Sie fortfahren möchten oder nicht, kann es ziemlich lange dauern. Sie könnten es in eine separate Funktion aufteilen, und das könnte am besten sein. Aber wenn Sie es in einer Funktion haben möchten und nicht triviale Arbeit zu erledigen ist, bevor Sie entscheiden, ob Sie fortfahren möchten, ist dieswhile(true)
möglicherweise am besten.gets()
ist keine übliche Konvention. Es ist sehr förderlich, Überläufe zu puffern.fgets(buffer, BUFFER_SIZE, file)
ist viel mehr wie Standardpraxis.fgets
.Es ist keine so schreckliche Sache, aber Sie müssen andere Entwickler beim Codieren berücksichtigen. Auch in der Schule.
Ihre Mitentwickler sollten in der Lage sein, die Exit-Klausel für Ihre Schleife in der Schleifendeklaration zu sehen. Das hast du nicht gemacht. Sie haben die Exit-Klausel in der Mitte der Schleife versteckt, um mehr Arbeit für jemanden zu machen, der mitkommt und versucht, Ihren Code zu verstehen. Dies ist der gleiche Grund, warum Dinge wie "Pause" vermieden werden.
Davon abgesehen werden Sie solche Dinge immer noch in einer Menge Code in der realen Welt sehen.
quelle
while (true)
es ziemlich offensichtlich, dass es einbreak
oderreturn
in ihr geben wird oder dass es für immer laufen wird. Unkompliziert zu sein ist wichtig, aber anwhile(true)
sich nicht besonders schlecht. Variablen mit komplexen Invarianten über Schleifeniterationen hinweg wären ein Beispiel für etwas, das viel mehr Angst verursacht.Es ist deine Waffe, deine Kugel und dein Fuß ...
Es ist schlecht, weil Sie um Ärger bitten. Sie oder eines der anderen Poster auf dieser Seite haben keine Beispiele für kurze / einfache while-Schleifen.
Das Problem wird zu einem sehr zufälligen Zeitpunkt in der Zukunft beginnen. Dies kann durch einen anderen Programmierer verursacht werden. Dies kann die Person sein, die die Software installiert. Es könnte der Endbenutzer sein.
Warum? Ich musste herausfinden, warum eine 700K LOC-App allmählich 100% der CPU-Zeit verbrennt, bis jede CPU gesättigt ist. Es war eine erstaunliche while (wahre) Schleife. Es war groß und böse, aber es lief darauf hinaus:
Es gab keinen letzten Zweig. Wenn der Wert nicht mit einer if-Bedingung übereinstimmte, lief die Schleife bis zum Ende der Zeit weiter.
Natürlich beschuldigte der Programmierer die Endbenutzer, keinen vom Programmierer erwarteten Wert ausgewählt zu haben. (Ich habe dann alle Instanzen von while (true) im Code entfernt.)
IMHO ist es keine gute defensive Programmierung, Konstrukte wie while (true) zu verwenden. Es wird zurückkommen, um dich zu verfolgen.
(Aber ich erinnere mich an die Bewertung von Professoren, wenn wir nicht jede Zeile kommentiert haben, auch nicht für i ++;)
quelle
Es ist in dem Sinne schlecht, dass strukturierte Programmierkonstrukte (den etwas unstrukturierten) Anweisungen zum Brechen und Fortfahren vorgezogen werden. Im Vergleich dazu werden sie nach diesem Prinzip dem "Gehe zu" vorgezogen.
Ich würde immer empfehlen, Ihren Code so strukturiert wie möglich zu gestalten ... obwohl Jon Skeet darauf hinweist, sollten Sie ihn nicht strukturierter gestalten!
quelle
Nach meiner Erfahrung haben Schleifen in den meisten Fällen die "Hauptbedingung", um fortzufahren. Dies ist die Bedingung, in die der while () - Operator selbst geschrieben werden sollte. Alle anderen Bedingungen, die die Schleife unterbrechen können, sind sekundär, nicht so wichtig usw. Sie können als zusätzliche
if() {break}
Anweisungen geschrieben werden.while(true)
ist oft verwirrend und weniger lesbar.Ich denke, dass diese Regeln nicht 100% der Fälle abdecken, sondern wahrscheinlich nur 98%.
quelle
Obwohl dies nicht unbedingt eine Antwort darauf ist, warum man es nicht verwendet
while (true)
, habe ich immer diese komische und begleitende Aussage des Autors gefunden eine prägnante Erklärung, warum man es tut, anstatt es zu tun.In Bezug auf Ihre Frage: Es gibt kein inhärentes Problem mit
... wenn Sie wissen, was Sie tun und sicherstellen, dass dies
exit_time
irgendwann ausgewertet wirdtrue
.Lehrer raten von der Verwendung ab,
while(true)
da es eine einfache Möglichkeit ist, einen kritischen Fehler zu machen, bis Sie genau wissen, was Sie tun.quelle
exit_time = false; while(!exit_time) { execute_stuff(); }
unddo { execute_stuff(); } while(! exit_time );
sind beide viel klarer als einif( condition ) { break; }
am Ende einer Schleife mit einemwhile(true)
. Unterbrechungen sind Kurzschlüsse zu Schleifen - vollkommen in Ordnung, wenn sie als Kurzschluss in der Mitte einer Schleife verwendet werden. Sie sollten jedoch nur eine Bedingung in der while-Anweisung als eine Unterbrechung am Ende einer Schleife bewerten.Sie können einfach ein Boolesches Flag verwenden, um anzugeben, wann die while-Schleife beendet werden soll.
Break
undgo to
waren Gründe dafür, dass Software zu schwer zu warten ist - die Software-Krise (tm) - und sollten vermieden werden und können es auch leicht sein.Es ist eine Frage, ob Sie pragmatisch sind oder nicht. Pragmatische Programmierer könnten in dieser einfachen Situation nur break verwenden.
Aber es ist gut, die Gewohnheit zu bekommen, sie nicht zu verwenden, sonst könnten Sie sie in ungeeigneten Situationen aus dem Habbit heraus verwenden, wie in komplizierten verschachtelten Schleifen, in denen die Lesbarkeit und Wartbarkeit Ihres Codes durch die Verwendung schwieriger wird
break
.quelle
if (running)
innerhalb der Schleife haben muss, um den gesamten Rest des Codes einzurücken, wenn ich nur die Schleife verlassen möchte, ist mir definitiv weniger klar als eine einfache break-Anweisung, die genau angibt , was ich tun möchte. Sie scheinen zu erwägen, Pause axiomatisch als schlechte Angewohnheit zu verwenden - ich sehe das nicht als solche.Vielleicht habe ich Pech. Oder vielleicht fehlt mir einfach eine Erfahrung. Aber jedes Mal, wenn ich mich erinnere,
while(true)
dassbreak
es darum ging , drinnen zu sein, war es möglich, den Code zu verbessern, indem die Extraktionsmethode auf while-Block angewendet wurde , wodurch daswhile(true)
aber (zufällig?) Allebreak
s inreturn
s transformierte .Nach meiner Erfahrung
while(true)
ohne Pausen (dh mit Rückschlägen oder Würfen) sind sie recht bequem und leicht zu verstehen.quelle
Ich denke, dass es ja ziemlich schlecht ist ... oder zumindest für viele Entwickler. Es ist symptomatisch für Entwickler, die nicht über ihre Schleifenbedingungen nachdenken. Folglich ist es fehleranfällig.
quelle
Es gibt kein großes Problem mit
while(true)
mitbreak
Aussagen, denken einige können jedoch seine leicht die Lesbarkeit des Codes senkt. Versuchen Sie, Variablen aussagekräftige Namen zu geben und Ausdrücke an der richtigen Stelle auszuwerten.Für Ihr Beispiel scheint es viel klarer zu sein, etwas zu tun wie:
Dies gilt insbesondere dann, wenn die do while-Schleife lang wird - Sie wissen genau, wo überprüft wird, ob eine zusätzliche Iteration stattfindet. Alle Variablen / Funktionen haben auf der Abstraktionsebene entsprechende Namen. Die
while(true)
Aussage besagt, dass die Verarbeitung nicht an dem Ort erfolgt, an dem Sie gedacht haben.Vielleicht möchten Sie beim zweiten Mal durch die Schleife eine andere Ausgabe. Etwas wie
scheint mir dann lesbarer zu sein
Wiederum sind beide mit einem trivialen Beispiel gut lesbar; Wenn die Schleife jedoch sehr groß oder tief verschachtelt wurde (was bedeutet, dass Sie sie wahrscheinlich bereits überarbeitet haben sollten), ist der erste Stil möglicherweise etwas klarer.
quelle
Ich verwende in vielen meiner Funktionen etwas Ähnliches, aber mit entgegengesetzter Logik.
quelle
Es ist eher eine ästhetische Sache, viel einfacher zu lesender Code, bei dem Sie explizit wissen, warum die Schleife direkt in der Deklaration der Schleife stoppt.
quelle
Ich würde sagen, dass der Grund dafür, dass dies keine gute Idee ist, im Allgemeinen darin besteht, dass Sie das Konstrukt nicht in vollem Umfang nutzen. Außerdem neige ich dazu zu denken, dass es vielen Programmierlehrern nicht gefällt, wenn ihre Schüler mit "Gepäck" hereinkommen. Damit meine ich, dass sie gerne den primären Einfluss auf den Programmierstil ihrer Schüler haben. Vielleicht ist das nur ein kleiner Ärger des Ausbilders.
quelle
Für mich ist das Problem die Lesbarkeit.
Eine while-Anweisung mit einer wahren Bedingung sagt nichts über die Schleife aus. Es macht die Aufgabe, es zu verstehen, viel schwieriger.
Was wäre aus diesen beiden Ausschnitten leichter zu verstehen?
quelle
Ich denke, wenn Sie Ihrem Lehrer eine Pause geben, brechen Sie einen Ast eines Baumes, um die Früchte zu erhalten. Verwenden Sie einige andere Tricks (beugen Sie den Ast), damit Sie die Früchte bekommen und der Ast noch lebt. :)
quelle
1) Mit a ist nichts falsch
do -while(true)
2) Dein Lehrer ist falsch.
NSFS !!:
3) Die meisten Lehrer sind Lehrer und keine Programmierer.
quelle
Es kann schlecht sein, wenn Ihre Schleife in einem Hintergrundthread ausgeführt wird. Wenn Sie also Ihre Anwendung durch Beenden eines UI-Threads schließen, wird dieser Code weiterhin ausgeführt. Wie andere bereits sagten, sollten Sie immer eine Art Scheck verwenden, um eine Möglichkeit zur Stornierung bereitzustellen.
quelle