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

break и continue

Вернёмся на беговую дорожку. До сих пор бегун останавливался, только когда кончались круги или условие становилось ложным. Но бывает, что цель достигнута посреди дистанции и бегать дальше незачем. Тогда бегун сходит с дорожки сразу.

Цикл, который что-то ищет, ведёт себя так же: найдя нужное, он должен остановиться. Инструкция break завершает цикл сразу. Эта программа ищет первое число больше 50, которое делится на 7:

SWIFT
for n in 51...100 {
    if n % 7 == 0 {
        print(n) // 56
        break
    }
}

Два способа изменить ход цикла

break и continue работают в любом цикле: в for-in, while и repeat-while.

break

break — бегун сходит с дистанции. Строки тела ниже break не выполняются, новых итераций не будет, и программа продолжается со строки после цикла.

Разберём пример по итерациям:

  1. Для n от 51 до 55 остаток от деления на 7 не равен нулю, и цикл идёт дальше.
  2. При n, равной 56, условие истинно, и программа печатает 56.
  3. break завершает цикл, и числа от 57 до 100 не проверяются.

break стоит внутри if, но завершает весь цикл, а не только if.

continue

continue — бегун срезает остаток текущего круга и сразу выходит на следующий. Цикл не заканчивается: for-in берёт следующее значение, а while снова проверяет условие, и тело начинается заново.

SWIFT
for n in 1...6 {
    if n % 3 == 0 {
        continue
    }
    print(n, terminator: " ") // 1 2 4 5
}

Числа 3 и 6 делятся на 3, поэтому для них continue пропускает print. Если заменить continue на break, программа напечатает только 1 2: цикл закончится при n, равной 3.

Здесь картинка с бегуном неточна: бегун решает сам, когда сойти с дорожки. break и continue срабатывают, только когда выполнение дошло до их строки, поэтому обычно их ставят внутри if.

Вложенные циклы

Цикл внутри другого цикла называют вложенным. На дорожке это тренировка из нескольких подходов: в каждом подходе бегун пробегает свои круги. На каждой итерации внешнего цикла внутренний проходит все свои итерации заново.

Так перебирают пары чисел. Эта программа ищет пары a и b от 1 до 3, сумма которых равна 5:

SWIFT
for a in 1...3 {
    for b in 1...3 {
        if a + b == 5 {
            print(a, b, terminator: "; ") // 2 3; 3 2;
            break
        }
    }
}

Разберём, что делает break:

  1. При a, равной 1, ни одна сумма не равна 5, и внутренний цикл проходит все три итерации.
  2. При a, равной 2, сумма 2 + 3 равна 5: программа печатает пару, и break завершает внутренний цикл.
  3. Внешний цикл продолжает работу, и при a, равной 3, находится пара 3 2.

break завершает только тот цикл, в теле которого стоит. Здесь это внутренний цикл. Подход закончился, но тренировка идёт дальше.

break с меткой

А если нужна только первая пара? Тогда выйти надо сразу из обоих циклов. Для этого внешнему циклу дают метку — имя с двоеточием перед словом for: search: for a in 1...3. Имя метки придумывают сами: search, outer или любое другое. Инструкция break search завершает цикл с этой меткой вместе со всеми циклами внутри него.

Это не метка аргумента из урока про print. Та стоит перед значением при вызове функции, а метка цикла стоит перед самим циклом и даёт ему имя.

Нажмите «Следующий шаг» и следите за константами a и b: после break search исчезают обе, а итерации с a, равной 3, не будет.

Вживуюbreak с меткойшаг 1 из 11 · рамок: 1

Внешний цикл начинает первую итерацию, и константа a равна 1.

Следите, когда появляются и исчезают константы a и b

Обычный break заканчивает подход, а break с меткой — всю тренировку. С меткой работает и continue: continue search сразу переходит к следующей итерации внешнего цикла.

На собеседовании часто спрашивают, как выйти сразу из двух вложенных циклов. Ответ: поставить метку на внешний цикл и написать break с этой меткой.

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

break написали внутри switch, который стоит в цикле:

SWIFT
for n in 1...5 {
    switch n {
    case 3:
        break // ✗
    default:
        print(n, terminator: " ")
    }
}

Хотели остановить цикл на тройке, а программа печатает 1 2 4 5. Внутри switch обычный break выходит только из switch, как в пустом case, и цикл идёт дальше. Поставьте на цикл метку и выйдите по ней: с numbers: for n in 1...5 и break numbers программа напечатает 1 2.

Главное

  • break сразу завершает цикл, а continue пропускает остаток текущей итерации и переходит к следующей.
  • Во вложенных циклах обычный break завершает только тот цикл, в теле которого стоит.
  • break с меткой внешнего цикла, например break search, выходит сразу из обоих циклов.
  • Внутри switch обычный break выходит только из switch, а цикл завершает break с меткой.