Powiązany artykuł na pewno dobrze mówi o pętlach N + 1/2 Donalda Knutha . Wyrażony w C / C ++ / Java:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
Jest to przydatne do odczytywania wierszy lub znaków z pliku, sprawdzania, czy osiągnięto EOF, a następnie przetwarzania go. Jestem tak przyzwyczajony do tego, for(;;)..if(..)break;że pojawia się wzór, że jest to dla mnie idiomatyczne. (Zanim przeczytałem artykuł Knutha, przedrukowany w książce Literate Programming , ten kiedyś był „wtf?”.)
Knuth zasugerował słowa kluczowe loop/while/repeat:
loop:
S;
while C:
T;
repeat
Gdzie Si Tsą symbolami zastępczymi dla serii zer lub więcej instrukcji i Cjest to warunek logiczny. Gdyby nie było Sinstrukcji, byłaby to pętla while, a gdyby nie było Tinstrukcji, byłaby to pętla do.
Konstrukcję tę można uogólnić, dopuszczając zero lub więcej while Cklauzul, co czyni ją idealną do wyrażania nieskończonych pętli, a następnie niektórych rzadszych warunków, które wymagałyby dwóch kontroli.
W tym samym artykule Knuth zasugerował mechanizm sygnalizacyjny, który byłby lokalną wersją wyjątków rzucania / wyłapywania (jako alternatywa dla używania goto).
Dla mnie? Chciałbym, aby Java wspierała optymalizację połączeń ogonowych, aby w razie potrzeby móc wyrazić dowolną ogólną strukturę sterowania.
Aktualizacja: zapomniałem wspomnieć, że wielu programistów C / C ++ / Java obchodzi ten problem, używając wbudowanego przypisania pod warunkiem while:
while ((c = getc(f)) != -1) {
T;
}
Używając terminów z konstruktu Knutha, jest to dopuszczalne, gdy Si Cmożna je połączyć w jedno wyrażenie. Niektórzy ludzie nienawidzą zobaczyć wbudowanego zadanie wyżej, inni nienawidzą, aby zobaczyć breakw for (;;)góry. Ale kiedy Si Cnie można go łączyć, na przykład gdy Sma wiele instrukcji, for (;;)jest to jedyna alternatywa bez powtarzania kodu. Inną alternatywą jest po prostu skopiowanie Skodu:
S;
while (C) {
T;
S;
}
loop/while/repeatAlternatywa Knutha wydaje się znacznie lepsza.