Warum sehe ich so viele für (;;) Konstrukte? [geschlossen]


14

Meines Erachtens wird eine for-Schleife verwendet, um einen bekannten oder bestimmbaren Bereich zu durchlaufen.

String[] names = //something;
for ( int i = 0; i < names.length; i++ ) { //do stuff }

Das ist äquivalent (Umfang von i beiseite) zu:

String[] names = //something;
int i = 0;
while (i < names.length )
{
   // do stuff
   i++;
}

Mit anderen Worten, die forSchleife ist einfach ein (sehr nützlicher) syntaktischer Zucker für ein häufig verwendetes whileKonstrukt.

Ich sehe jedoch viele for(;;)Konstrukte im Web, die funktional äquivalent zu sindwhile(true)

Was ist die Begründung dafür? Warum sollte die Endlosschleife der Endlosschleife while vorgezogen werden?

// Ich habe sogar ein Java-Lehrbuch gesehen, das überhaupt keine while-Schleifen verwendet hat! Dies führt zu solchen monströsen Konstrukten wie:

String input = getInput();
for( ; !inputIsValid(input) ; )
{
   //redo;
}

Der Hauptgrund ist die Präferenz. Lesbarkeit sollte bei der Auswahl jedoch YMMV ins Spiel kommen.
Aaron McIver

Warum sollte jemand das peinliche Konstrukt vorziehen?
Chris Cudmore

10
Du könntest tauschen whileund forhier und die Frage würde sich nicht ändern. while(true)und for(;;)meine das Gleiche. Sie haben offensichtlich eine starke Vorliebe für while, andere mögen eine ebenso starke Vorliebe für haben for. Es ist unmöglich zu sagen, dass einer korrekter ist als der andere.
Caleb

3
@chris, ich finde das überhaupt nicht for(;;)verwirrend. Es ist eine Standard-C-Sprache, die Sie in Abschnitt 3.5 von K & R (2e) dokumentiert haben. Ich verstehe, dass es dir nicht gefällt. Sie sollten verstehen, dass andere es offensichtlich bevorzugen (sonst würden Sie es nie sehen). Es kann in anderen Sprachen als C mehr oder weniger akzeptabel sein; Sie haben diesen Sprachunabhängigen markiert, was die Möglichkeit einer endgültigen Antwort nur verringert. Auch hier stimmte ich zu schließen , weil die Q nicht konstruktiv ist; Wenn ich beleidigt gewesen wäre, hätte ich statt oder zusätzlich zum Schließen als beleidigend gekennzeichnet. Das ist alles.
Caleb

1
Persönlich denke ich, dass es hier eine echte Gelegenheit gibt, eine andere Syntax für Endlosschleifen zu haben: so etwas wiewheeeeeeee { ... }
Detly,

Antworten:


33

Es ist ein Überbleibsel aus alten Programmierpraktiken auf dem PDP-11 (ja, ich sagte alt ). Es wurde ein einzelner Befehl gespeichert, was nützlich war, um Schleifen schneller laufen zu lassen.

Weitere Informationen finden Sie im Folgenden: http://www.flounder.com/exceptions.htm


3
Genau das habe ich gesucht. Es gibt einen echten, legitimen Grund, aber er ist nicht mehr gültig.
Chris Cudmore

1
@chris Nnnope, moderne Compiler beschweren sich manchmal über die Verwendung einer Konstante im Zustand einer Schleife. Es ist nicht nur ein Überbleibsel.
Izkata

Es steckt mehr dahinter. Ich kann mich erinnern, C in den frühen 90ern auf Unix-Systemen geschrieben zu haben, und während (true) {} keine Option war. Es gab keinen Standard-Booleschen Typ, aber mehrere Unix-Systeme definierten ihre eigenen in C-Header-Dateien. Aus dem Speicher definierte mindestens ein Unix-Anbieter TRUE als Null, um die Verarbeitung von Funktionsrückgaben zu unterstützen, da die Konvention lautete, bei Erfolg Null zurückzugeben, und positive Zahlen waren Fehler. Dies bedeutete, dass while (TRUE) {} nicht portierbar war.
Michael Shaw

1
Ich kann es momentan nicht finden, aber ich könnte schwören, dass Dennis Ritchie vor ein paar Jahren einen Beitrag über das Usenet geschrieben hat, in dem er feststellt, dass dies einfach falsch ist, und dass er die for(;;)Syntax (seiner Meinung nach) als direktere Aussage von verwendet Absicht, dass keine Kriterien für das Verlassen der Schleife angegeben wurden.
Jerry Coffin

@Ptolemy: Na das hättest du bestimmt schreiben können while(1) { }.
Ed S.

10

Einige Compiler geben bei der Verwendung eine Warnung aus (so etwas wie Bedingungsausdruck ist konstant ), while( 1 )aber for( ; ; )es gibt nichts, vor dem sie warnen müssen. Programmierer wollen Code ohne Warnungen, deshalb verwenden sie die for-Variante.


Einige Dinge, vor denen Compiler warnen, sind jedoch absolut gültig und sogar (in bestimmten Fällen) unvermeidbar. Deshalb behandeln einige von uns Warnungen als Warnungen. Wenn Sie sie ignorieren, können Sie sich natürlich in die verdammten Dinge stürzen und die wichtigen nicht sehen - aber es gibt Pragmas und Optionen zum Deaktivieren von Warnungen, lokal oder global. Grundsätzlich ist es ja besser, keine Warnungen zu haben, aber ich brauche normalerweise einen stärkeren Grund als diesen, um einen schlechteren Codestil anzunehmen. Hier ist es nicht schlimmer, nur anders, aber "Endlos" -Schleifen sind sowieso selten (oder sehr schlecht).
Steve314

5

Es ist eine Gewohnheit, die durch C-Programmierung erworben wurde, bei der es keinen Booleschen Typ gibt. Zwar wäre (1) möglicherweise das Äquivalent, aber For (;;) wird oft verwendet, wie es in K & R angezeigt wird, wenn ich mich richtig erinnere. Ich vermute, dass es irgendwo auch einen Hardware-Grund gab.


4
... vermute, es gab einen Grund für die Hardware ...
Aaron McIver

2
Wie Edward Robertson erwähnte, liegt der Grund darin, dass der C-Compiler auf dem PDP-11 nicht erkannte, dass "while (true)" eine Kompilierungszeitkonstante ist, und beim Generieren einer Assembly eine zusätzliche Anweisung (einen Vergleich) hinzufügte. Aufgrund der begrenzten Ressourcen, die auf dem PDP-11 verfügbar sind, haben Programmierer die for-Schleife verwendet, um diesen einen zusätzlichen Befehl aus dem Programm zu optimieren.
Jetti

3

denn (;;) kann als "für immer" gelesen werden, was manche natürlicher finden als "solange es wahr ist".


Obwohl dies nicht der ursprüngliche Grund ist, ist es ein sekundärer Grund, warum die Präferenz lange nach dem Veralten des ursprünglichen Grundes stecken blieb. Es ist jedoch sehr schwierig, Beweise dafür zu finden, als erfahrene Programmierer zu befragen.
DarenW

-2

Alle erfahrenen Programmierer, die ich gefragt habe, können for(;;)schneller als while(true)oder erkennen while(1).


2
Jeder Programmierer, der etwas wert ist, sollte in der Lage sein, alle drei sofort zu erkennen. Alle drei sind so verbreitet, dass jeder, der mehr als 5 Minuten mit dem Lesen von Code verbracht hat, sie ein paarmal gesehen hat.
cHao

1
Studien haben gezeigt, dass erfahrene Programmierer for(;;)14 ms schneller verstehen können als while(1):-)
Kevin Cline
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.