L'article lié comprend clairement les boucles N + 1/2 de Donald Knuth . Exprimé en C / C ++ / Java:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
Ceci est utile pour lire des lignes ou des caractères d'un fichier, tester si vous avez atteint EOF, puis le traiter. Je suis tellement habitué à voir le motif for(;;)..if(..)break;
apparaître qu'il est idiomatique pour moi. (Avant d'avoir lu l'article de Knuth, réimprimé dans le livre Literate Programming , celui-ci était un "wtf?".)
Knuth a suggéré les mots clés loop/while/repeat
:
loop:
S;
while C:
T;
repeat
Où S
et T
sont les espaces réservés pour une série de zéro ou plusieurs instructions, et C
est une condition booléenne. S'il n'y avait pas de S
déclaration, ce serait une boucle while, et s'il n'y avait pas de T
déclaration, ce serait une boucle do.
Cette construction elle-même pourrait être généralisée en autorisant zéro ou plusieurs while C
clauses, ce qui la rend parfaite pour exprimer des boucles infinies, puis des conditions plus rares qui nécessiteraient deux vérifications.
Dans le même article, Knuth a suggéré un mécanisme de signalisation qui serait une version locale des exceptions de lancement / capture (comme alternative à l'utilisation de goto).
Pour moi? Je souhaite que Java supporte l'optimisation des appels, afin que je puisse exprimer n'importe quelle structure de contrôle générale selon les besoins.
Mise à jour: j'ai oublié de mentionner que de nombreux programmeurs C / C ++ / Java contournent celui-ci en utilisant une affectation intégrée dans l'état de while
:
while ((c = getc(f)) != -1) {
T;
}
En utilisant les termes de la construction de Knuth, cela est permis quand S
et C
peut être combiné en une seule expression. Certaines personnes détestent voir l'affectation intégrée ci-dessus, tandis que d'autres détestent voir break
ce qui for (;;)
précède. Mais quand S
et C
ne peut pas être combiné, comme quand S
a plusieurs instructions, le for (;;)
est la seule alternative sans répéter le code. L'autre alternative est de simplement dupliquer le S
code:
S;
while (C) {
T;
S;
}
L' loop/while/repeat
alternative de Knuth semble bien meilleure.