while и do-while
Чему вы научитесь:
- повторять код циклами
while,do-whileиforи выбирать подходящий цикл для задачи; - предсказывать, сколько раз выполнится тело цикла и в каком порядке работают части заголовка
for; - отличать
i++от++i, когда их значение идёт дальше в выражение; - пропускать итерацию через
continue, выходить из цикла черезbreak, а из двух циклов сразу — по метке.
Представьте бегуна на стадионе. Тренер сказал ему: «Бегай круги, пока не пробежишь три». У старта висит табло с номером круга.
Перед каждым кругом бегун смотрит на табло: если номер не больше трёх, он бежит этот круг. После круга номер на табло растёт на единицу. Когда он становится больше трёх, бегун сходит с дорожки.
Программам тоже постоянно нужно повторять одно и то же: напечатать сто строк, сложить тысячу чисел, делить число на 10, пока от него что-то остаётся. Писать сто одинаковых инструкций подряд долго, а часто и нельзя: заранее неизвестно, сколько повторов понадобится. Для этого есть цикл — конструкция, которая выполняет блок кода снова и снова, пока её условие истинно.
Вот бегун из примера, записанный на Java:
public class Main {
public static void main(String[] args) {
int lap = 1;
while (lap <= 3) {
System.out.print(lap + " "); // 1 2 3
lap++;
}
}
}Давайте разберём программу по строкам:
int lap = 1;— на табло номер первого круга.while (lap <= 3)проверяет условие.1 <= 3истинно, поэтому выполняется блок в фигурных скобках.System.out.print(lap + " ")печатает номер круга и пробел.lap++прибавляет кlapединицу: круг пробежан, на табло2.- Выполнение возвращается к
whileи снова проверяет условие. Для2и3всё повторяется, а приlap, равной4, условие4 <= 3ложно, и цикл заканчивается.
Программа печатает 1 2 3.
Как работает while
Цикл while состоит из трёх частей:
- ключевое слово
while— по-английски «пока»; - условие в круглых скобках — как и в
if, оно должно иметь типboolean; - тело цикла — блок в фигурных скобках, который повторяется.
Один проход тела называют итерацией. В примере три итерации: для lap, равной 1, 2 и 3.
while всегда работает в одном порядке:
- Проверить условие.
- Если оно истинно, выполнить тело и вернуться к шагу 1.
- Если ложно, перейти к инструкции после цикла.
Условие проверяется перед каждой итерацией, и перед первой тоже. Если оно ложно с самого начала, тело не выполнится ни разу. Бегун посмотрел на табло, увидел там 4 и даже не вышел на дорожку.
Чтобы цикл когда-нибудь закончился, тело должно менять то, что проверяет условие. В примере это делает lap++.
do-while: сначала круг, потом проверка
У while есть родственник, который проверяет условие в конце. Его записывают так: do { тело } while (условие);. Части этой записи:
- ключевое слово
do— по-английски «делай» — открывает тело; - тело в фигурных скобках;
whileс условием в круглых скобках после закрывающей скобки тела;- точка с запятой в конце: вся запись — одна инструкция.
Порядок здесь обратный: сначала тело, потом проверка. Поэтому тело do-while выполняется хотя бы один раз, даже если условие ложно с самого начала. Это главное отличие от while, и о нём часто спрашивают на собеседованиях.
На стадионе так устроен разминочный круг: бегун пробегает его сразу, а на табло смотрит только после.
Где это нужно? Например, когда считают цифры числа. Число делят на 10 и считают деления, пока оно не станет нулём:
int n = 4096;
int digits = 0;
do {
digits++;
n = n / 10;
} while (n != 0);
System.out.println(digits); // 4Целое деление отбрасывает последнюю цифру, поэтому n меняется так: 4096, 409, 40, 4, 0. Тело выполнилось четыре раза, и digits равна 4.
Теперь возьмём n, равную 0. Ноль записывается одной цифрой, и do-while это учитывает: тело выполняется один раз, digits становится 1, а условие 0 != 0 ложно. А вот while с тем же условием даёт неверный ответ:
int n = 0;
int digits = 0;
while (n != 0) {
digits++;
n = n / 10;
}
System.out.println(digits); // 0while проверил условие перед первой итерацией, увидел, что 0 != 0 ложно, и не выполнил тело ни разу. Отсюда правило выбора:
while— когда тело может не понадобиться ни разу;do-while— когда тело нужно выполнить хотя бы раз, а повторять ли его, решает результат этого прохода.
Частая ошибка
В теле забыли изменить переменную из условия:
int lap = 1;
while (lap <= 3) { // ✗
System.out.print(lap + " ");
}Переменная lap всегда равна 1, условие 1 <= 3 всегда истинно, и программа печатает 1 1 1 … без конца. Такой цикл называют бесконечным. Сама программа не остановится: в терминале её прерывают сочетанием клавиш Ctrl+C.
Здесь картинка со стадионом расходится с Java. Настоящий бегун рано или поздно устанет и сойдёт с дорожки сам. Цикл не устаёт: если номер на табло никто не меняет, он будет бегать вечно. Добавьте lap++; в конец тела, и цикл напечатает 1 2 3.
Главное
whileпроверяет условие перед каждой итерацией, поэтому тело может не выполниться ни разу.do-whileпроверяет условие после тела, поэтому тело выполняется хотя бы один раз; в конце записи нужна;.- Тело цикла должно менять то, что проверяет условие, иначе цикл станет бесконечным.