In dem verlinkten Artikel geht es definitiv um Donald Knuths N + 1/2-Loops . In C / C ++ / Java ausgedrückt:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
Dies ist nützlich, um Zeilen oder Zeichen aus einer Datei zu lesen, um zu prüfen, ob Sie EOF erreicht haben, und um sie dann zu verarbeiten. Ich bin es so gewohnt, das Muster zu sehen for(;;)..if(..)break;
, dass es für mich idiomatisch ist. (Bevor ich den Artikel von Knuth gelesen hatte, der im Buch Literate Programming abgedruckt war , war dieser ein "wtf?".)
Knuth schlug die Schlüsselwörter vor loop/while/repeat
:
loop:
S;
while C:
T;
repeat
Wo S
und T
sind Platzhalter für eine Reihe von null oder mehr Anweisungen und C
ist eine boolesche Bedingung. Wenn es keine S
Anweisung gäbe, wäre es eine while-Schleife, und wenn es keine T
Anweisung gäbe, wäre es eine do-Schleife.
Dieses Konstrukt selbst könnte verallgemeinert werden, indem null oder mehr while C
Klauseln zugelassen werden, was es perfekt macht, um Endlosschleifen und dann einige seltenere Bedingungen auszudrücken, die zwei Überprüfungen erfordern würden.
Im selben Artikel schlug Knuth einen Signalisierungsmechanismus vor, der eine lokale Version von Ausnahmen für das Werfen / Fangen von Ausnahmen ist (als Alternative zur Verwendung von goto).
Für mich? Ich wünsche mir, dass Java die Tail-Call-Optimierung unterstützt, damit ich bei Bedarf eine allgemeine Kontrollstruktur ausdrücken kann .
Update: Ich habe vergessen zu erwähnen, dass viele C / C ++ / Java-Programmierer dieses Problem umgehen, indem sie eine eingebettete Zuweisung verwenden, unter der Bedingung, dass while
:
while ((c = getc(f)) != -1) {
T;
}
Unter Verwendung der Begriffe aus Knuths Konstrukt ist dies zulässig, wenn S
und C
kann zu einem einzigen Ausdruck kombiniert werden. Einige Leute hassen es, die eingebettete Aufgabe oben zu sehen, während andere es hassen, break
die for (;;)
oben genannte Aufgabe zu sehen . Aber wenn S
und C
kann nicht kombiniert werden, beispielsweise wenn S
mehrere Anweisungen hat, das for (;;)
ist die einzige Alternative , ohne Code zu wiederholen. Die andere Alternative besteht darin, den S
Code einfach zu duplizieren :
S;
while (C) {
T;
S;
}
Knuths loop/while/repeat
Alternative scheint viel besser zu sein.