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

Циклы while и do…while

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

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

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

Чтобы сложить числа от 1 до 100, пришлось бы написать сто слагаемых подряд. Так никто не делает: повторяющееся действие поручают циклу — конструкции, которая выполняет блок кода снова и снова.

Представьте беговую дорожку. Перед каждым кругом бегун проходит контрольную арку, и там ему говорят, бежать ли дальше. Пробежав круг, он делает отметку в счётчике кругов. Когда арка отвечает «хватит», бегун сходит с дорожки.

Цикл while устроен так же: перед каждым кругом он проверяет условие и, пока оно истинно, выполняет свой блок. Вот сумма чисел от 1 до 100:

PHP
<?php

$total = 0;
$i = 1;
while ($i <= 100) {
    $total += $i;
    $i++;
}
echo $total, "\n"; // 5050
echo $i, "\n"; // 101

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

  1. $total = 0; заводит сумму.
  2. $i = 1; — счётчик кругов: бегун начинает с первого.
  3. while ($i <= 100) — контрольная арка: условие в круглых скобках проверяется перед каждым кругом.
  4. $total += $i; прибавляет номер круга к сумме.
  5. $i++; делает отметку в счётчике: $i увеличивается на единицу.
  6. Первый echo выполняется уже после цикла и печатает 5050.

Условие проверяется перед витком

Блок в фигурных скобках называют телом цикла. Один проход тела — это виток, или итерация.

Главное в while — порядок событий:

  1. PHP проверяет условие.
  2. Если оно истинно, выполняется тело и всё повторяется с первого шага.
  3. Если условие ложно, цикл заканчивается и программа идёт дальше.

Поэтому после цикла в $i лежит 101, а не 100. Последний виток сделал $i равным 101, условие 101 <= 100 оказалось ложным, и цикл закончился. Второй echo это и печатает.

На собеседовании любят такие вопросы: сколько раз выполнится тело и что окажется в счётчике после цикла. Ответ всегда даёт одно правило: условие проверяется перед витком.

Здесь картинка с бегуном неточна. Бегун пробегает хотя бы один круг, а while проверяет условие ещё до первого витка. Если начать с $i = 200, тело не выполнится ни разу и сумма останется 0.

Бесконечный цикл

Если условие никогда не станет ложным, цикл сам не закончится. Такой цикл называют бесконечным.

Чаще всего он появляется случайно: представьте, что в первом примере забыли строку $i++. Тогда $i навсегда остаётся 1, условие 1 <= 100 истинно всегда, и бегун бежит круг за кругом без отметок.

PHP не выводит об этом никакого сообщения: программа молча работает, пока её не остановят. В терминале это делает сочетание клавиш Ctrl+C.

Иногда бесконечный цикл пишут нарочно, через while (true), и заканчивают его изнутри — например, через return в функции. Эта функция ищет первое число, квадрат которого больше $limit:

PHP
function firstSquareOver($limit)
{
    $n = 1;
    while (true) {
        if ($n * $n > $limit) {
            return $n;
        }
        $n++;
    }
}

echo firstSquareOver(50), "\n"; // 8

Разберём вызов firstSquareOver(50):

  1. Поиск начинается с $n = 1.
  2. Для $n от 1 до 7 квадрат не больше 50, и цикл идёт дальше.
  3. При $n, равном 8, квадрат равен 64, и return возвращает 8: функция заканчивается вместе с циклом.

Цикл do…while

do…while — вариант while, который сначала выполняет тело и только потом проверяет условие. Его тело выполняется хотя бы один раз, как у настоящего бегуна, который сверяется со счётом уже после круга.

PHP
$n = 10;
while ($n < 5) {
    echo 'while ', $n, "\n";
    $n++;
}
do {
    echo 'do ', $n, "\n"; // do 10
    $n++;
} while ($n < 5);

Давайте посмотрим, что здесь происходит:

  1. Условие 10 < 5 ложно с самого начала, поэтому тело while не выполняется ни разу.
  2. do выполняет тело без проверки и печатает do 10.
  3. Только потом while ($n < 5) проверяет условие: 11 < 5 ложно, и цикл заканчивается.

Обратите внимание на точку с запятой после while ($n < 5). В do…while условие стоит последним и закрывает всю инструкцию.

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

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

После условия в do…while забыли точку с запятой:

PHP
$n = 1;
do {
    echo $n, "\n";
    $n++;
} while ($n <= 3) // ✗
echo 'done', "\n";
TEXT
Parse error: syntax error, unexpected token "echo", expecting ";"

PHP ждал ; после условия, а встретил следующий echo. Как вы уже знаете, ошибка разбора не даёт запуститься всему файлу: не выполнится ни одна строка, даже те, что стоят выше. Исправление — } while ($n <= 3);.

Главное

  • while проверяет условие перед каждым витком и выполняет тело, пока условие истинно.
  • После цикла в счётчике лежит значение, на котором условие стало ложным: 101, а не 100.
  • Цикл, условие которого никогда не становится ложным, называют бесконечным; в терминале его останавливает Ctrl+C.
  • do…while сначала выполняет тело, потом проверяет условие, и после while (…) ставится ;.