Программа описывает последовательность операций для компьютера для выполнения. Среди этих операций могут быть некоторые подпоследовательности, которые компьютер должен повторять несколько раз. Вместо того, чтобы буквально повторять эти подпоследовательности соответствующее количество раз в исходном коде программы (что во многих случаях невозможно), вы можете использовать конструкцию, которая сообщает компьютеру, что в конце такой подпоследовательности он должен вернуться или «зацикнуть» назад к началу этой подпоследовательности. Эти типы конструкций условно называются «петлями».
В некоторых случаях повторяющаяся подпоследовательность самих операций содержит подпоследовательность операций, которая должна повторяться несколько раз как часть выполнения одной итерации содержащейся последовательности. Это тоже можно представить с помощью конструкции цикла.
Пример: алгоритм для очистки окон в моем доме
- Получить моющие средства из шкафа
- Если больше нет грязных окон, то остановиться. Else,
- Перейти к следующему грязному окну.
- Спрей-очиститель
- Протрите окно
- Если это не достаточно чистый, то вернитесь к шагу 3,1
- Вернитесь к шагу 2.
Это имеет две петли: внешнее один из которых содержит каждый шаг, кроме первого, и внутренний, содержащий этапы с 3.1 по 3.3.
Часто возникает какая-то инициализация или начальное состояние, которое должно быть достигнуто до начала цикла. В этом примере я должен иметь свои принадлежности для чистки, прежде чем я смогу очистить все окна, и я хочу начать с первого окна.
В большинстве интересных случаев вы не знаете заранее, сколько раз программа должна будет проходить через заданный цикл. В примере, например, я мог бы предсказать число итераций внешнего цикла как количество окон в моем доме, но я не могу быть уверен, сколько итераций внутреннего цикла будет необходимо для любого заданного окна. Конструкции петли обрабатывают это, предоставляя гибкие условия для завершения цикла.
С другой стороны, что-то должно измениться с итерации на итерацию, иначе повторение никогда не остановится. В простейшем случае вещь, которая изменяется на триггер, в конечном итоге прерывается от цикла, (абстрактно) - количество уже выполненных итераций цикла. Часто, однако, нам нужна более гибкая оценка того, нужны ли еще итерации, например, «достаточно ли еще окна?»
Катушка for
C/Java формализует эти три элемента: инициализация (получение расходных материалов), условие завершения (есть ли более грязные окна?) И обновление (переход к следующему окну). Шаг инициализации выполняется один раз, перед первой итерацией. Условие завершения тестируется перед каждой итерацией (и цикл завершается, если он оценивается до false
), а шаг обновления выполняется после каждой итерации перед тестированием условия завершения для следующей итерации. Когда цикл завершается нормально, компьютер следующий выполняет оператор сразу после тела цикла.
Чтобы продолжить глупый пример:
for (
int window_number = 0;
window_number < TOTAL_NUMBER_OF_WINDOWS;
window_number = window_number + 1) {
Window currentWindow = windows[window_number];
do {
cleaner.spray(currentWindow);
cloth.wipe(currentWindow);
} while (currentWindow.isDirty());
}
В этом случае я представлял внутреннюю петлю с другой конструкцией петли (do { ... } while
), так как он подходит более естественно с фактами, что есть ни один шаг инициализации не требуется, я не нужно проверять завершение до первой итерации, а шаг обновления выполняется внутри тела цикла. Тем не менее, на самом деле было бы неинтересно тестировать условие завершения до первой итерации, однако я могу написать внутренний цикл как цикл for
.Я просто оставить части мне не нужен пустой (но я всегда нужны два точкой с запятой разделителей):
for (
int window_number = 0;
window_number < TOTAL_NUMBER_OF_WINDOWS;
window_number = window_number + 1) {
Window currentWindow = windows[window_number];
for (
/* no initialization */ ;
currentWindow.isDirty();
/* no (additional) update */) {
cleaner.spray(currentWindow);
cloth.wipe(currentWindow);
}
}
И это все, что вам нужно знать о циклах в целом и for
петель, в частности.