Перейти к содержимому
Теория · Циклы · урок 1 из 8

while и do-while

Чему вы научитесь

Чему вы научитесь:

  • повторять код циклами while, do-while и for и выбирать подходящий цикл для задачи;
  • предсказывать, сколько раз выполнится тело цикла и в каком порядке работают части заголовка for;
  • отличать i++ от ++i, когда их значение идёт дальше в выражение;
  • пропускать итерацию через continue, выходить из цикла через break, а из двух циклов сразу — по метке.

Представьте бегуна на стадионе. Тренер сказал ему: «Бегай круги, пока не пробежишь три». У старта висит табло с номером круга.

Перед каждым кругом бегун смотрит на табло: если номер не больше трёх, он бежит этот круг. После круга номер на табло растёт на единицу. Когда он становится больше трёх, бегун сходит с дорожки.

Программам тоже постоянно нужно повторять одно и то же: напечатать сто строк, сложить тысячу чисел, делить число на 10, пока от него что-то остаётся. Писать сто одинаковых инструкций подряд долго, а часто и нельзя: заранее неизвестно, сколько повторов понадобится. Для этого есть цикл — конструкция, которая выполняет блок кода снова и снова, пока её условие истинно.

Вот бегун из примера, записанный на Java:

JAVA
public class Main {
    public static void main(String[] args) {
        int lap = 1;
        while (lap <= 3) {
            System.out.print(lap + " "); // 1 2 3
            lap++;
        }
    }
}

Давайте разберём программу по строкам:

  1. int lap = 1; — на табло номер первого круга.
  2. while (lap <= 3) проверяет условие. 1 <= 3 истинно, поэтому выполняется блок в фигурных скобках.
  3. System.out.print(lap + " ") печатает номер круга и пробел.
  4. lap++ прибавляет к lap единицу: круг пробежан, на табло 2.
  5. Выполнение возвращается к while и снова проверяет условие. Для 2 и 3 всё повторяется, а при lap, равной 4, условие 4 <= 3 ложно, и цикл заканчивается.

Программа печатает 1 2 3.

Как работает while

Цикл while состоит из трёх частей:

  • ключевое слово while — по-английски «пока»;
  • условие в круглых скобках — как и в if, оно должно иметь тип boolean;
  • тело цикла — блок в фигурных скобках, который повторяется.

Один проход тела называют итерацией. В примере три итерации: для lap, равной 1, 2 и 3.

while всегда работает в одном порядке:

  1. Проверить условие.
  2. Если оно истинно, выполнить тело и вернуться к шагу 1.
  3. Если ложно, перейти к инструкции после цикла.

Условие проверяется перед каждой итерацией, и перед первой тоже. Если оно ложно с самого начала, тело не выполнится ни разу. Бегун посмотрел на табло, увидел там 4 и даже не вышел на дорожку.

Чтобы цикл когда-нибудь закончился, тело должно менять то, что проверяет условие. В примере это делает lap++.

do-while: сначала круг, потом проверка

У while есть родственник, который проверяет условие в конце. Его записывают так: do { тело } while (условие);. Части этой записи:

  • ключевое слово do — по-английски «делай» — открывает тело;
  • тело в фигурных скобках;
  • while с условием в круглых скобках после закрывающей скобки тела;
  • точка с запятой в конце: вся запись — одна инструкция.

Порядок здесь обратный: сначала тело, потом проверка. Поэтому тело do-while выполняется хотя бы один раз, даже если условие ложно с самого начала. Это главное отличие от while, и о нём часто спрашивают на собеседованиях.

На стадионе так устроен разминочный круг: бегун пробегает его сразу, а на табло смотрит только после.

Где это нужно? Например, когда считают цифры числа. Число делят на 10 и считают деления, пока оно не станет нулём:

JAVA
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 с тем же условием даёт неверный ответ:

JAVA
int n = 0;
int digits = 0;
while (n != 0) {
    digits++;
    n = n / 10;
}
System.out.println(digits); // 0

while проверил условие перед первой итерацией, увидел, что 0 != 0 ложно, и не выполнил тело ни разу. Отсюда правило выбора:

  • while — когда тело может не понадобиться ни разу;
  • do-while — когда тело нужно выполнить хотя бы раз, а повторять ли его, решает результат этого прохода.

Частая ошибка

В теле забыли изменить переменную из условия:

JAVA
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 проверяет условие после тела, поэтому тело выполняется хотя бы один раз; в конце записи нужна ;.
  • Тело цикла должно менять то, что проверяет условие, иначе цикл станет бесконечным.