ВВЕРХ
ВНИЗ

Операторы break, continue и exit

Добрый день! Если вы используете в своей программе циклы, то время от времени вам понадобится или досрочно выйти из цикла, или пропустить несколько последних операторов в цикле. В таком случае без операторов break и continue вам не обойтись. Плюс к этому, иногда есть необходимость досрочно выйти из процедуры или функции, или вообще завершить программу – тогда используется оператор exit. Но нужно ещё запомнить, что операторы BREAK и CONTINUE применяются только внутри циклов.

Сначала дадим определение оператору break, а continue и exit ниже.

break — это оператор, предназначенный для досрочного выхода из цикла.

По английски break означает "перерыв", "прервать", и это слово хорошо знакомо боксерам. При его использовании программа немедленно выходит из цикла, продолжая выполнять последующие за циклом операторы. Так, если вы выполняете в цикле некоторую работу (вычисления), но при определенных условиях все дальнейшие вычисления бессмысленны, то смело задействуйте оператор break – он мгновенно выведет вас из цикла. Это как обеденный перерыв или дешевый хостинг для сайта, от которых трудно отказаться. Так и оператор break или exit, МГНОВЕННО завершающие работу в нужный момент. Но следует помнить, что оператор break прерывает только тот цикл, в котором он вызван, и это надо учитывать при использовании вложенных циклов. Приведем примеры.

Напечатаем все символы английского алфавита от "a" до "m".

Причем, будем перебирать все буквы подряд, а после попадания буквы "m" выйдем из цикла.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
var
  ch: char; { <-- переменная ch символьного типа }

begin
  { Перебираем все символы английского алфавита }
  for ch := 'a' to 'z' do
  begin
    write(ch:2); //выводим символ
    { Когда встречаем символ 'm', выходим из цикла: }
    if ch = 'm' then break
  end;
  readln
end.

В строке 8 кода выводим букву ch (параметр цикла), а ниже проверяем равенство её букве "m". Если равенство выполняется, то выходим из цикла. Поскольку после цикла в коде программы есть только оператор readln – ожидание нажатия клавиши Enter, – то после её нажатия программа на этом завершается.

"УГАДАЙКА ДЕЛИТЕЛЬ". Программа "задумывает" число от 1000 до 1999, а вам нужно угадать делитель этого числа, то есть целое число, делящее нацело "задуманное" машиной.

Сначала в строках 5, 6 задаем границы a и b интервала случайных чисел (вместо указанных 1000 и 1999 можете взять свои параметры). В 9 строке находим случайное число n с диапазона [1000, 1999], а в 11 строке после запроса вводим делитель d по своему желанию. Если этот делитель не равен 0 и делит нацело число n (строчка 12 кода), то выводим соответствующее сообщение; в противном случае выходим из цикла (строка 14) и сообщаем о неудаче (строка 17).

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
var
  a, b, n, d: integer;

begin
  a := 1000;
  b := 1999;
  randomize;
  repeat
    n := a + random(b - a + 1); { число 1000..1999 }
    write('Введите целое число --> ');
    readln(d);
    if (d <> 0) and (n mod d = 0) then
      writeln('  ', n, ' делится на ', d)
    else break
  until false;
  writeln;
  writeln(n, ' НЕ ДЕЛИТСЯ НА ', d, '!');
  readln
end.

Одно из моих испытаний выглядит таким образом:

Введите целое число --> 1
  1590 делится на 1
Введите целое число --> 2
  1616 делится на 2
Введите целое число --> 3
  1080 делится на 3
Введите целое число --> 5

1584 НЕ ДЕЛИТСЯ НА 5!

Задача. Выводить случайные целые числа с диапазона 0..99 до тех пор, пока не встретится число, большее 90. И так 10 раз с новой строчки.

Для генерации случайных чисел задействуем датчик псевдослучайных чисел (5 строка), а потом процедуру random(100) для вывода целых случайных чисел с диапазона 0..99 (строка 10 кода). Поскольку вывод чисел до первого большего 90 надо повторять 10 раз, то внешний цикл берем с параметром от 1 до 10 (строка 6). Тогда внутренний цикл мы не можем брать с параметром, поскольку не известно заранее количество повторений. Здесь воспользуемся циклом с предусловием while (условие) do, причем само условие вхождения в цикл будет всегда истинно, то есть True (строка 8). А выйдем из цикла с помощью оператора break при первом же попавшемся числе, большим 90 (строка 12). После выхода из цикла переходим на следующую строку оператором writeln (15 строка кода), и повторим все сначала в общем количестве 10 раз.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
var
  i, n: integer;

begin
  randomize;
  for i := 1 to 10 do { <-- повторяем 10 раз }
  begin
    while true do
    begin
      n := random(100); { <-- случайное число 0..99 }
      write(n:3); { <-- выводим число }
      if n > 90 then break { <-- если число 
      большее 90 – выходим из цикла }
    end;
    writeln { <-- переходим на следующую строку }
  end;
  readln
end.

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

 70 69 91
 94
 23 62 72 94
 75 41 29  5 60 34 87 22 71  4 86 20 39 94
 49 47 92
 82  9 44 43 23 43 16 91
 97
 25 55 10 72 94
 42 95
 30 52 18 18 51 11 25 20  0 96

Другие примеры использования оператора досрочного выхода из цикла break посмотрите в задачах Array43 (второй вариант решения) и задание Array44 там же; в другом разделе Proc28 и Proc31 решебника Абрамяна. Возможно, где-то ещё найдете, я уже не помню.


Далее рассмотрим оператор continue.

continue — этот оператор предназначенный для завершения текущей итерации цикла и переходу к концу тела цикла.

На английском continue означает "продолжать". Исходя из определения, если в цикле прогаммы встречается оператор continue, то все последующие за ним операторы пропускаются, осуществляя переход к концу цикла. Далее все зависит от вида цикла – с параметром или с условием. Если цикл с параметром (цикл for) или цикл с предусловием (while), то сразу переходим в начало и проверяем условие входа в цикл; если цикл с послеусловием (repeat), то прорверяется условие выхода из цикла. Но продемонстрируем сказанное на примерах.

По аналогии с предыдущей задачей, будем выводить случайные числа.

Задача. Из 10 случаных чисел с диапазона [-100, 99] вывести только положительные.

Каждый раз, как мы получим отрицательное число (строки кода 8, 9), оператор continue отправит нас в самый конец цикла, пропуская вывод этого числа в строке 10.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
var
  i, n: integer;

begin
  randomize;
  for i := 1 to 10 do { <-- повторяем 10 раз }
  begin
    n := -100 + random(200); { диапазон чисел - [-100, 99] }
    if n < 0 then continue;
    write(' ', n) { <-- выводим число }
  end;
  readln
end.

Можете запустить программу несколько раз и понаблюдать: ни в одном из случаев вы не увидите отрицательного числа – это нам гарантирует оператор continue. Вы получите приблизительно такой результат:

 75 96 30 24 93 80 92

Как видим из примера, хотя мы повторяли вычисления 10 раз, но получили только 7 чисел. Это значит, что остальные 3 были отрицательными, и 3 раза оператор вывода в строке 10 был пропущен.

Задача. Для 10 случаных чисел с интервала (-10, 10) вычислить их квадратные корни.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
var
  i: integer;
  a: real;

begin
  i := 0;
  writeln('| число | корень  |');
  writeln(' -----------------');
  while i < 10 do begin
    inc(i);
    a := -10 + 20 * random;
    if a < 0 then begin
      writeln('|', a:5:3,' | ', '|':9);
      continue
    end;
    writeln('| ', a:5:3, ' | ', sqrt(a):6:5, ' |')
  end;
  readln
end.

Один из моих результатов выглядит следующим образом:

| число | корень  |
 -----------------
| 0.613 | 0.78319 |
|-9.488 |         |
|-9.477 |         |
| 0.271 | 0.52054 |
|-1.345 |         |
| 7.410 | 2.72210 |
| 6.992 | 2.64423 |
|-4.853 |         |
| 3.491 | 1.86841 |
| 0.091 | 0.30220 |

Как видно, для отрицательных чисел корни квадратные отсутствуют – это нам гарантирует условный оператор в строке 12, где выводим только значение a без корня, а потом continue (продолжаем далее).


И, наконец, переходим к оператору exit.

exit — это оператор, предназначенный для досрочного выхода из процедуры или функции и возвращения в основную программу. Вызов оператора exit в основной программе приводит к её завершению.

Пример использования EXIT. Вычислить квадратный корень из введенного пользователем числа.

Поскольку в области действительных чисел из отрицательного числа квадратный корень извлечь не возможно, то если введенное нами число (строка 6) окажется отрицательным, то выходим из программы с сообщением "ошибка!" (строки 7-11). Причем, сообщение нужно писать до вызова оператора exit, иначе после выхода из программы ни один оператор не выполнится.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
var
  x: real;
  
begin
  write('Введите число --> ');
  readln(x);
  if x < 0 then
  begin
    writeln('ERROR!');
    exit
  end;
  writeln('Корень квадратный = ', sqrt(x):0:5);
  readln
end.

Как видим, оператор exit можно использовать и вне цикла – и в этом его отличие от операторов break и continue, которые, как отмечалось, вызываются только внутри цикла.

Вызов EXIT в цикле. Вычислять квадратные корни введенных чисел до первого отрицательного числа.

Цикл используем с предусловием, где условие true – всегда истинно. Это значит, что такой цикл будет продолжаться "вечно", если мы не выйдем из него оператором break или exit. Мы выберем второй. Это предыдущая программа, только обрамленная циклом while. При первом же отрицательном числе мы выходим из условия if, а заодно и цикла.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
var
  x: real;

begin
  while true do
  begin
    write('Введите число --> ');
    readln(x);
    if x < 0 then
    begin
      writeln('ERROR!');
      exit
    end;
    writeln('  корень квадратный = ', sqrt(x):0:5);
    writeln
  end
end.

Вот, что примерно должно у вас получится:

Введите число --> 23
  корень квадратный = 4.79583

Введите число --> 5
  корень квадратный = 2.23607

Введите число --> 12
  корень квадратный = 3.46410

Введите число --> 100
  корень квадратный = 10.00000

Введите число --> 333
  корень квадратный = 18.24829

Введите число --> -894
ERROR!

Теперь приведем пример, как делается вызов EXIT в подпрограмме (процедуре или функции). В данном случае воспользуемся функцией.

"СДЕЛАЙ ПОСЛЕДНИЙ ХОД и проиграй ". Компьютер "загадывает" число, потом делается ход – указывается произвольное число и вычисляется общая сумма с прежними слагаемыми. Проигрывает тот, на чьем ходу сумма окажется больше "задуманного" числа. Палаллельно подсчитывается процентное соотношение суммы "правильно" введенных чисел (которые не привели к проигрышу).
Какое число "загадал" компьютер – не известно. Известны только границы "задуманного" числа и границы "вводимых" компьютером чисел, поэтому и пользователь ДОЛЖЕН вводить свои числа в таких же границах, иначе – тоже проигрыш. Первым делает ход пользователь.

Код Pascal
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
const
   { ДИАПАЗОН ЗАДУМАННОГО КОМПЬЮТЕРОМ ЧИСЛА: }
  D1 = 0;  { <-- левая граница }
  D2 = 50; { <-- правая граница }
   { ГРАНИЦЫ ВВОДИМЫХ ЧИСЕЛ: }
  a = 0;  { <- минимальная граница }
  b = 10; { <- максимальная граница }

var
  counter: integer;
  Q, percent: real;

procedure summ(memory: real);
var
  y: real;
begin
  inc(counter); { <-- увеличиваем ход на 1 }
  if odd(counter) then
  begin
    write('Введите число --> ');
    readln(y);
    { Если число выходит за границы, то выходим: }
    if (y < a) or (y > b) then begin
      writeln;
      write('НАРУШЕНИЕ ПРАВИЛ: число за границами диапазона [', a, '; ', b, ']!');
      exit
    end
  end
  else begin
    write('Ход компьютера --> ');
    y := a + (b - a) * random; { <- число в диапазоне [a; b) }
    sleep(1000);
    writeln(y:0:3)
  end;
  Q := Q + y; { <-- увеличиваем общую сумму }
  if (Q > memory) then exit
  else begin
    percent := (Q / memory) * 100; { <- приближенность к загаданой сумме (в процентах) }
    summ(memory) { <== снова вызываем процедуру }
  end
end;

var
  memory: integer;

begin
  randomize;
  Q := 0; { начальная общая сумма }
  counter := 0; { начальное количество ходов }
  memory := D1 + random(D2 - D1 + 1); { "задуманное" число }
  writeln('Компьютер уже "задумал" число от ', D1, ' до ', D2, '.');
  writeln('Позволено вводить числа с диапазона [', a, '; ', b, ']');
  writeln;
  summ(memory); { <== ВЫЗОВ ПРОЦЕДУРЫ }
  writeln;
  if odd(counter) then writeln('ВЫ ПРОИГРАЛИ!')
  else writeln('КОМПЬЮТЕР ПРОИГРАЛ.');
  writeln;
  writeln('  Было задумано число ', memory);
  writeln('  Последняя сумма: ', Q:0:3);
  writeln('  Приближенность к выиграшу: ', percent:0:3, '%');
  readln
end.

Вот, как примерно выглядит "проигрыш" компьютера при испытаниях:

Компьютер уже "задумал" число от 0 до 50.
Позволено вводить числа с диапазона [0; 10]

Введите число --> 1
Ход компьютера --> 2.641
Введите число --> 2
Ход компьютера --> 1.221
Введите число --> 4
Ход компьютера --> 4.698
Введите число --> 2.901
Ход компьютера --> 7.407

КОМПЬЮТЕР ПРОИГРАЛ.

  Было задумано число 23
  Последняя сумма: 25.867
  Приближенность к выиграшу: 80.262%

Здесь есть такие ключевые параметры: memory – число, "задуманное" компьютером; counter – общее количество сделанных ходов; Q – общая сумма введенных чисел (компьютером и человеком); percent – процентное отношение набранной суммы к задуманной сумме memory. А еще есть диапазоны: задуманное число – от D1 до D2, число для ввода – от a до b (строки 1 – 7 в разделе описания констант).

Но эта программа не имеет стратегии – вы просто вводите числа, которые суммируются. Если набирается сумма больше "задуманного" memory, то программа завершается. Чтобы выиграть, вы должны вводить числа поменьше. А поскольку компьютер ничем не ограничен, то рано или поздно проиграет. Ведь пользователь просто каждый раз может вводить 0: тогда на его ходе сумма увеличиваться не будет, а на ходе компьютера – да, а это уже нечестно.

Но можно доработать программу уже со стратегией таким образом: если вы начинаете вводить маленькие числа, то компьютер это "замечает" и тоже начинает генерировать слагаемые поменьше – в результате общая сумма будет медленно расти. А при таком раскладе выиграть уже сложнее. Можно указать и другие правила или ограничения, фантазия не ограничена.

На этом, наверное, все. Пишите в комментариях, что можно ещё добавить. Пока!


Яндекс.Метрика