Root /ArchiveAbout
()

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

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

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

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

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

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

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

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

var
  ch: char; { <-- переменная ch символьного типа }

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

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

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

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

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.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647

  1. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  2. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). A **mod** B - остаток при целочисленном делении А на В **const** false = False;: Представляет логическое значение. Одно из моих испытаний выглядит таким образом:

Задача. Выводить случайные целые числа с диапазона 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 раз.

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.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647

  1. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности. **const** true = True;: Представляет логическое значение.
  2. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). У каждого будет свой набор чисел, так как мы находили случайные числа. Вот, к примеру, что у вас должно получится:

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

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

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

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

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

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

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

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.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647

  1. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  2. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). Можете запустить программу несколько раз и понаблюдать: ни в одном из случаев вы не увидите отрицательного числа – это нам гарантирует оператор continue. Вы получите приблизительно такой результат:

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

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

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.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1

  1. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). **function** Sqrt(x: real): real;: Возвращает квадратный корень числа x. Один из моих результатов выглядит следующим образом:

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

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

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

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

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

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

**type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **function** Sqrt(x: real): real;: Возвращает квадратный корень числа x. Как видим, оператор exit можно использовать и вне цикла – и в этом его отличие от операторов break и continue, которые, как отмечалось, вызываются только внутри цикла.

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

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

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.

**type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **const** true = True;: Представляет логическое значение. **function** Sqrt(x: real): real;: Возвращает квадратный корень числа x. Вот, что примерно должно у вас получится:

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

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

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.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 **function** Odd(i: integer): boolean;: Возвращает True, если i нечетно

  1. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). **procedure** Sleep(ms: integer);: Делает паузу на ms миллисекунд **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647
  2. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  3. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). **function** Odd(i: integer): boolean;: Возвращает True, если i нечетно Вот, как примерно выглядит "проигрыш" компьютера при испытаниях:

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

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

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

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