Глиф Учебники

Урок 5. Циклы — for, while и repeat

Курс «Pascal» · урок 5 из 9 · 3 минуты чтения

Цикл повторяет действия много раз: вывести числа от 1 до 100, сложить все введённые числа, спрашивать пароль, пока не введут верный. В Pascal три цикла, и у каждого своё назначение.

for — когда известно, сколько раз

Pascal
program Squares;
var
  i: integer;
begin
  for i := 1 to 5 do
    writeln(i, ' в квадрате = ', i * i);
end.
Вывод
1 в квадрате = 1
2 в квадрате = 4
3 в квадрате = 9
4 в квадрате = 16
5 в квадрате = 25

Переменная i — параметр цикла — сама принимает значения 1, 2, 3, 4, 5, и для каждого выполняется оператор после do. Параметр должен быть целого типа (или char) и описан в разделе var, как обычная переменная.

Чтобы считать вниз, вместо to пишут downto:

Pascal
program Countdown;
var
  i: integer;
begin
  for i := 5 downto 1 do
    write(i, ' ');
  writeln('Старт!');
end.
Вывод
5 4 3 2 1 Старт!
for i := 1 to 5 do +1 1 2 3 4 5 for i := 5 downto 1 do −1 5 4 3 2 1 Старт!
С to параметр i идёт от 1 до 5, каждый раз прибавляя единицу, с downto — от 5 до 1, вычитая единицу; после последнего шага программа переходит к строке за циклом и выводит «Старт!».

Правила for:

Накопление суммы

Типичная задача — сложить много чисел. Заводят переменную-«копилку», обнуляют её до цикла и в цикле прибавляют очередное значение:

Pascal
program SumToN;
var
  n, i: integer;
  s: longint;
begin
  readln(n);
  s := 0;
  for i := 1 to n do
    s := s + i;
  writeln('Сумма от 1 до ', n, ' = ', s);
end.
Ввод
10
Вывод
Сумма от 1 до 10 = 55
s := 0; for i := 1 to n do s := s + i; при n = 10 программа выводит Сумма от 1 до 10 = 55 i s + i s до цикла s := 0 0 1 0 + 1 1 2 1 + 2 3 3 3 + 3 6 ⋮ ⋮ ⋮ 9 36 + 9 45 10 45 + 10 55
До цикла копилку s обнуляют, а на каждом шаге к ней прибавляется очередное i: 0 + 1 = 1, 1 + 2 = 3, 3 + 3 = 6 и так до 45 + 10 = 55.

Сумма описана как longint: для n = 1000 она равна 500 500 и в integer Free Pascal не поместится.

while — пока условие верно

while проверяет условие перед каждым повтором. Его берут, когда число повторов заранее неизвестно:

Pascal
program Doubling;
var
  x, steps: integer;
begin
  x := 1;
  steps := 0;
  while x <= 1000 do
  begin
    x := x * 2;
    steps := steps + 1;
  end;
  writeln('Шагов: ', steps, ', число: ', x);
end.
Вывод
Шагов: 10, число: 1024

Программа удваивает число, пока оно не станет больше 1000. Если условие ложно с самого начала, тело while не выполнится ни разу.

Внутри while что-то обязательно должно менять условие. Если забыть x := x * 2, условие будет верно всегда и программа зациклится. Остановить её можно командой «Завершить» (Ctrl+F2) в PascalABC.NET или клавишами Ctrl+C в консоли.

repeat … until — хотя бы один раз

repeat проверяет условие после тела цикла, поэтому тело выполняется минимум один раз. Цикл повторяется, пока условие ложно, и останавливается, когда оно станет истинным:

Pascal
program AskPositive;
var
  n: integer;
begin
  repeat
    writeln('Введите положительное число:');
    readln(n);
  until n > 0;
  writeln('Принято: ', n);
end.
Ввод
-3
0
8
Вывод
Введите положительное число:
Введите положительное число:
Введите положительное число:
Принято: 8

Между repeat и until можно писать сколько угодно операторов — begin … end там не нужен.

Обратите внимание на разницу условий: while работает, пока условие верно, а repeat — до тех пор, пока условие не станет верным. while x <= 1000 и until x > 1000 — одно и то же правило остановки.

while условие — перед телом x <= 1000 верно x := x * 2; steps := steps + 1; ложно выход repeat условие — после тела тело цикла readln(n); until n > 0 ложно верно выход
while проверяет условие перед телом и повторяет, пока оно верно; repeat сначала выполняет тело, потом проверяет until и повторяет, пока условие ложно.

break и continue

Pascal
program BreakDemo;
var
  i: integer;
begin
  for i := 1 to 100 do
  begin
    if i * i > 50 then
      break;
    if i mod 2 = 0 then
      continue;
    write(i, ' ');
  end;
  writeln;
end.
Вывод
1 3 5 7

Цикл выводит нечётные числа (continue пропускает чётные) и останавливается, как только квадрат числа превысит 50: 8 · 8 = 64.

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

Внутри цикла может стоять другой цикл. Для каждого значения внешнего параметра внутренний цикл проходит целиком:

Pascal
program Table;
var
  i, j: integer;
begin
  for i := 1 to 3 do
  begin
    for j := 1 to 5 do
      write(i * j:4);
    writeln;
  end;
end.
Вывод
   1   2   3   4   5
   2   4   6   8  10
   3   6   9  12  15

Формат :4 выводит каждое число в поле шириной 4 символа, поэтому столбцы ровные. writeln после внутреннего цикла переводит строку.

Какой цикл выбрать

ЦиклКогдаУсловие
forчисло повторов известно заранеенет, считает сам
whileповторять, пока что-то верно; может не выполниться ни разув начале, продолжать пока верно
repeatвыполнить хотя бы раз, например запросить вводв конце, остановиться когда верно

Частые ошибки

Коротко

Проверьте себя

1. Сколько раз выполнится тело цикла for i := 10 to 1 do?
2. Чем repeat … until отличается от while?
3. Что выведет программа?
Pascal
var
  i, s: integer;
begin
  s := 0;
  for i := 1 to 4 do
    s := s + i;
  writeln(s);
end.
4. Почему эта программа зависает?
Pascal
x := 5;
while x > 0 do
  writeln(x);