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

Урок 4. Условия — if и case

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

До сих пор программы выполняли все строки подряд. Но часто действие зависит от данных: число чётное или нечётное, пароль верный или нет, оценка высокая или низкая. Для этого есть условный оператор if и оператор выбора case.

if … then … else

Pascal
program EvenOdd;
var
  n: integer;
begin
  readln(n);
  if n mod 2 = 0 then
    writeln(n, ' — чётное')
  else
    writeln(n, ' — нечётное');
end.
Ввод
14
Вывод
14 — чётное
n = 14 n mod 2 = 0 true then writeln(n, ' — чётное') 14 — чётное else writeln(n, ' — нечётное') пропускается дальше
При n = 14 условие n mod 2 = 0 истинно, поэтому выполняется ветка then и выводится «14 — чётное», ветка else пропускается, и программа идёт дальше.

Читается как по-английски: «если n mod 2 = 0, то вывести „чётное“, иначе — „нечётное“». После then — то, что делается при выполненном условии, после else — при невыполненном. Ветку else можно не писать, тогда при ложном условии программа просто идёт дальше:

Pascal
if n < 0 then
  writeln('Число отрицательное');

Перед else точка с запятой не ставится. if … then writeln('да'); else … — ошибка компиляции: точка с запятой закончила бы оператор if, и else оказался бы «ничьим».

Сравнения

ЗнакЗначение
=равно
<>не равно
<, >меньше, больше
<=, >=меньше или равно, больше или равно

Сравнивать можно числа, символы и строки. Строки сравниваются по алфавиту, точнее по кодам символов: 'apple' < 'banana' — истина, а все большие латинские буквы «меньше» маленьких.

Несколько действий: begin … end

После then и else стоит один оператор. Если действий несколько, их объединяют в составной оператор begin … end:

Pascal
program Compare;
var
  a, b: integer;
begin
  readln(a, b);
  if a > b then
  begin
    writeln('Первое больше');
    writeln('Разница: ', a - b);
  end
  else
  begin
    writeln('Первое не больше второго');
    writeln('Разница: ', b - a);
  end;
end.
Ввод
3 10
Вывод
Первое не больше второго
Разница: 7

Обратите внимание: после первого end нет точки с запятой — за ним идёт else. Без begin … end к условию относилась бы только первая строка, а вторая выполнялась бы всегда.

Без begin … end if a > b then writeln('Первое больше'); writeln('Разница: ', a - b); выполнится всегда к if относится только первая строка С begin … end if a > b then begin writeln('Первое больше'); writeln('Разница: ', a - b); end begin … end объединяет обе строки
Без begin и end к условию if a > b относится только первая строка после then, а вторая выполняется всегда; begin и end объединяют обе строки в один составной оператор.

and, or, not

Условия соединяют логическими операциями:

Каждое сравнение рядом с and и or берут в скобки: (a > 0) and (b > 0). В Pascal and и or выполняются раньше сравнений, и без скобок запись a > 0 and b > 0 компилятор поймёт как a > (0 and b) > 0 и выдаст ошибку.

Пример — високосный год. Год високосный, если он делится на 4 и не делится на 100, или если делится на 400:

Pascal
program LeapYear;
var
  y: integer;
begin
  readln(y);
  if ((y mod 4 = 0) and (y mod 100 <> 0)) or (y mod 400 = 0) then
    writeln(y, ' — високосный год')
  else
    writeln(y, ' — обычный год');
end.
Ввод
2024
Вывод
2024 — високосный год

Для 1900 программа выведет «обычный год»: он делится на 100, но не на 400.

Вложенные условия

Внутри then или else может стоять ещё один if. Так проверяют несколько вариантов по очереди:

Pascal
program NumberSign;
var
  x: integer;
begin
  readln(x);
  if x > 0 then
    writeln('Положительное')
  else if x < 0 then
    writeln('Отрицательное')
  else
    writeln('Ноль');
end.
Ввод
-8
Вывод
Отрицательное

else всегда относится к ближайшему if перед ним, у которого ещё нет своего else. Если нужно иначе, внутренний if заключают в begin … end.

case — выбор из многих вариантов

Когда одна переменная сравнивается с несколькими значениями, цепочка if становится длинной. Удобнее case:

Pascal
program DayName;
var
  d: integer;
begin
  readln(d);
  case d of
    1: writeln('Понедельник');
    2: writeln('Вторник');
    3: writeln('Среда');
    4: writeln('Четверг');
    5: writeln('Пятница');
    6, 7: writeln('Выходной');
  else
    writeln('Такого дня нет');
  end;
end.
Ввод
6
Вывод
Выходной

Как устроен case:

В отличие от if, в case точка с запятой перед else допустима.

Пример с диапазонами — уровень по десятибалльной отметке:

Pascal
program Mark;
var
  m: integer;
begin
  readln(m);
  case m of
    1..2: writeln('Низкий уровень');
    3..4: writeln('Удовлетворительный уровень');
    5..6: writeln('Средний уровень');
    7..8: writeln('Достаточный уровень');
    9..10: writeln('Высокий уровень');
  else
    writeln('Отметка от 1 до 10');
  end;
end.
Ввод
8
Вывод
Достаточный уровень
case m of m = 8 0 else 11 else 1 2 1..2 Низкий уровень 3 4 3..4 Удовлетворительный уровень 5 6 5..6 Средний уровень 7 8 7..8 Достаточный уровень 9 10 9..10 Высокий уровень
Варианты-диапазоны case делят отметки от 1 до 10 на пять уровней: m = 8 попадает в диапазон 7..8, и выводится «Достаточный уровень», а для чисел вне диапазонов, например 0 или 11, выполняется else.

Если в одном варианте нужно несколько действий, их, как и в if, заключают в begin … end.

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

Коротко

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

1. Что не так в этой записи?
Pascal
if a > b then
  writeln('a');
else
  writeln('b');
2. Как правильно проверить, что x от 1 до 10 включительно?
3. Что выведет программа, если ввести 7?
Pascal
var
  d: integer;
begin
  readln(d);
  case d of
    1..5: writeln('Будни');
    6, 7: writeln('Выходной');
  else
    writeln('Ошибка');
  end;
end.
4. Зачем нужен begin … end после then?