Связанная статья определенно делает это правильно о петлях N + 1/2 Дональда Кнута . Выражается в C / C ++ / Java:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
Это полезно для чтения строк или символов из файла, проверки достижения EOF и последующей обработки. Я так привык видеть этот шаблон, for(;;)..if(..)break;
что он идиоматичен для меня. (До того, как я прочитал статью Кнута, перепечатанную в книге « Грамотное программирование» , эта статья была «wtf?».)
Кнут предложил ключевые слова loop/while/repeat
:
loop:
S;
while C:
T;
repeat
Где S
и T
являются местозаполнителями для ряда нулевых или более операторов, и C
это логическое условие. Если бы не было S
оператора, то это был бы цикл while, а если бы не было T
оператора, то это был бы цикл do.
Эту конструкцию можно обобщить, допуская ноль или более while C
предложений, что делает ее идеальной для выражения бесконечных циклов, а затем некоторых более редких условий, которые потребуют двух проверок.
В той же статье Кнут предложил механизм сигнализации, который будет локальной версией исключения / перехвата (в качестве альтернативы использованию goto).
Для меня? Я хотел бы, чтобы Java поддерживала оптимизацию хвостового вызова, чтобы я мог выражать любую общую структуру управления по мере необходимости.
Обновление: я забыл упомянуть, что многие программисты на C / C ++ / Java обходят это, используя встроенное присваивание в условии while
:
while ((c = getc(f)) != -1) {
T;
}
Используя термины из конструкции Кнута, это допустимо, когда S
и C
может быть объединено в одно выражение. Некоторые люди не хотят видеть внедренный назначение выше, в то время как другие ненавидят , чтобы увидеть break
в for (;;)
выше. Но когда S
и C
не могут быть объединены, например, когда S
имеет несколько операторов, for (;;)
единственная альтернатива без повторения кода. Другой вариант - просто продублировать S
код:
S;
while (C) {
T;
S;
}
loop/while/repeat
Альтернатива Кнута кажется намного лучше.