#9 Условный оператор IF (оператор ветвления if else) в Паскаль. Полная и неполная формы условного оператора. Вложенность условий
Primary tabs
Условный оператор -- что это такое
Условный оператор IF служит для программирования ситуаций выбора (моделирования различных вариантов развития ситуации, с которым мы сталкиваемся в жизни, но теперь уже внутри программы).
Структура условного оператора. Блочность
Условный оператор в общем виде состоит из трёх частей:
- Проверка логического значения
- Ветка истинности (обязательна) -- выполнится если логическое значение истинно (true)
- Ветка ложности (необязательна) -- выполнится если логическое значение ложно (false)
Сразу отметим, что логическое значение -- это фактически ответ на вопрос формата "да/нет" , напомним, что логическим типом значением обладают:
- логические литералы
- логические переменные
- и логические выражения
-- точно также как и любой простой тип данных может быть представлен литералами, переменными или выражениями из них.
В программном коде структуру условного оператора можно проиллюстрировать следующей схемой:
if (<логическое_значение>) then // проверка выражения и начало тела ветки истинности begin {здесь код, который выполнится, если логическое значение истинно} end else // начало ложной ветки (её тела) begin {здесь код, который выполнится, если логическое значение ложно} end; // конец ложной ветки и оператор ветвления
Например:
if ( 5 > 7) then // проверка выражения и начало тела ветки истинности begin writeln('5 > 7 верно'); writeln('5 > 7 верно'); end else // начало ложной ветки (её тела) begin writeln('5 > 7 неверно'); writeln('5 > 7 неверно'); end; // конец ложной ветки и оператор ветвления
-- в данном случае выполнится "ложная" ветка, так как $5 > 7$ возвращает результат false.
Точка с запятой перед else
Заметьте (см. примеры выше и ниже), что перед else точка с запятой не ставится.
Операторные скобки условного оператора
В предыдущем примере обратите внимание на операторные скобки, окружающие тела веток оператора ветвления -- begin и end необходимы, если в ветке выполняется более одной операции, если же в ветке содержится только одна операция, то операторные скобки не нужны.
Например для ситуации, изображённой на этой блок-схеме:
Эту же ситуацию можно проиллюстрировать кодом:
if ( 5 > 7) then // проверка выражения и начало тела ветки истинности writeln('5 > 7 верно'); // конец ветки истинности else // начало ложной ветки (её тела) writeln('5 > 7 неверно'); // конец ветки ложности
-- здесь в обеих ветках только одна операция, а потому операторные скобки не нужны.
Полная и неполная формы оператора IF
Оператор IF в программе может быть представлен в следующих формах:
- Полная форма -- форма оператора if, в которой присутствуют обе ветки -- и then и else
- Неполная форма -- форма в которой присутствует только then.
Полная форма условного оператора IF
В полной форме оператора IF присутствуют обе ветки -- именно полную форму мы рассматривали выше, например:
if (a > 5) then b := 2 // в ветки истинности одно действие else begin b := 3; // в ветки ложности два действия a := 2; end.
-- здесь в качестве условия мы сравнивали переменную с числом, а потом описывали два сценария, один из которых выполнится в зависимости от значения условия.
В последнем примере кода, у нас в ветке истинности одна операция, а в ветки ложности 2 -- эту ситуацию можно изобразить на блок-схеме так (с каким-то предварительным действием до if):
Неполная форма условного оператора IF
В неполной форме условного оператора есть только сценарий истинности, ветка ложности же вообще не описывается, например:
if (a > 5) then b := 2 // в ветки истинности одно действие
-- в ветке ложности здесь вообще ничего нет, то есть если $a$ не больше $5$, то и никаких действий предпринято не будет.
На блок-схеме неполная форма оператора ветвления выглядит так:
-- правило использования операторных скобок действует и здесь: если в ветке больше одной операции, то begin и end нужны.
Разбор задач
Пример №1 -- неполная форма IF
Сравните два числа, если первое больше второго, то выведите на экран "22" и затем отдельным вызовом writeln() число 555.
-- в этой задаче указано, что надо предпринимать какие-то действия только в одном случае ("если первое больше второго"), а значит будет использовать оператор ветвления в неполной форме:
var a,b: integer; begin writeln('vvedite dva celih chisla: '); readln(a, b); if (a > b) then // сравниваем begin writeln(22); writeln(555); end; readln(); end.
-- в ветке истинности здесь было две операции, а потому мы использовали для неё операторные скобки.
Пример №2 -- полная форма, по одному действию в каждой ветке
Сравните два числа, если первое больше второго, то выведите на экран "22", а иначе выведете на экран 'abc'.
-- в этой задаче указаны два альтернативных действия, а потому будем использовать оператор ветвления в его полной форме:
var a,b: integer; begin writeln('vvedite dva celih chisla: '); readln(a, b); if (a > b) then // сравниваем writeln(22) // если да else writeln('abc'); // если нет readln(); end.
-- обратите внимание, что перед else точка с запятой не ставится.
Пример №3 - логические выражения и оператор ветвления IF
Задача:
Коля набрал $k$ баллов, Миша $n$ баллов, а Петя $d$ баллов в ходе соревнований. Если:
- сумма баллов Коли и Миши больше $20$
- и сумма баллов Пети и Миши меньше $55$
--то тогда вывести в консоль сообщение о том, что ничья, в противном случае вывести сообщение, что победил Коля.
В этой в качестве условия требуется выполнение сразу двух подусловий, причем не одного из них -- а двух одновременно, потому в логическом выражении для if мы будем использовать логическую операцию AND, тогда можно решить как-то так:
var k, n, d: integer; // переменные для хранения баллов, набранных ребятами begin // сначала получаем данные от пользователя writeln('vvedite chislo ballov Koli: '); readln(k); writeln('vvedite chislo ballov Mishi: '); readln(n); writeln('vvedite chislo ballov Peti: '); readln(d); // далее начинаем проверку условий if ((k + n > 20) AND (n + d < 55)) then // используем "логическое И" (одновременность) writeln('Pobedila druzhba!') else writeln('Pobedil Kolya!'); readln(); end.
Пример №4 - вложенные условные операторы
Операторы могут вкладываться один в другой так, как как это показано на блок-схеме (на деле внутренний оператор вкладывается в одну из веток внешнего):
Рассмотрим задачу, решение которой будет соответствовать этой блок-схеме:
Получите от пользователя два целых числа, если первое больше второго, то выведите на экран их сумму, а затем их разность, иначе:
- сначала сравните их сумму с числом $25$, если она больше, то выведите на экран первое число, а если меньше, то второе.
- затем выведите на экран второе число в квадрате
Реализуем решение в виде программы:
var a,b: integer; begin writeln('vvedite dva celih chisla: '); readln(a, b); if (a > b) then begin writeln('ih summa:', a + b); writeln('ih raznost:', a - b); end // перед else точка с запятой не ставится даже после end else begin { вложенные оператор условия -- первая вложенная операция в ветке ложности внешнего оператора } if ((a + b) > 25) then writeln('vivodim peroe:', a) else writeln('vivodim vtoroe:', b); // конец вложенного оператора ветвления и его ветки ложности (так как нет операторных скобок, то к ветке вложенности относится только одна операция) writeln(b*b); // вторая вложенная операция end; readln(); // удерживаем косоль end.
Пример №5 - вложенные условные операторы
Например задачу из более раннего примера:
Коля набрал $k$ баллов, Миша $n$ баллов, а Петя $d$ баллов в ходе соревнований. Если:
- сумма баллов Коли и Миши больше $20$
- и сумма баллов Пети и Миши меньше $55$
--то тогда вывести в консоль сообщение о том, что ничья, в противном случае вывести сообщение, что победил Коля.
можно было бы решить с помощью вложенных блоков условного оператора IF:
program Project1; var k, n, d: integer; // переменные для хранения баллов, набранных ребятами begin // сначала получаем данные от пользователя writeln('vvedite chislo ballov Koli: '); readln(k); writeln('vvedite chislo ballov Mishi: '); readln(n); writeln('vvedite chislo ballov Peti: '); readln(d); // далее начинаем проверку условий if ((k + n) > 20) then if ((n + d) < 55) then // вкладываем второе условие writeln('Pobedila druzhba!') else writeln('Pobedil Kolya!') else writeln('Pobedil Kolya!'); readln(); end.
-- обратите внимание, что begin и end не нужны для ветки истинности внешнего оператора, так как в него вложен лишь один if -- а остальные строки относятся к этому вложенному if.
ВАЖНО: В этом приме здесь налицо дублирование кода, что является плохим стилем. Более того вложенные блоки в коде труднее понимать, поэтому:
Если можно не использовать вложенность -- не используйте её, лучше используйте более сложные условия с логическими операциями.
Пример №6 - жизненный выбор
То есть ситуацию, в которую попал богатырь на этой иллюстрации:
Можно запрограммировать следующим образом:
{Программа жизненного выбора} program qwe; var a: integer; // число, означающее выбор пользователя (богатыря) res: string; // его будущее begin writeln ('vvedite: 1 esli napravo, 2 esli pryamo, 3 esli nalevo '); readln(a); // читаем, куда пойдёт пользователь // далее определяем будущее if (a = 1) then res := ' konya poteryaesh ' else if (a = 2) then res := ' zhenat budesh ' else if (a = 3) then res := ' ubitum budesh ' else // если пользователь выбрал что-то другое res := ' buduchee ne izvestno '; writeln('otvet: ', res); readln(); end.
- по сути это тоже несколько вложенных один в другой операторов ветвления, причем вложение здесь на всех двух младших уровнях происходит в ветку ложности.
Пример №7 Вложение оператора if в неполной форме в оператор if в полной форме
При решении задач или при просмотре/анализе кода написанного не вами может возникнуть проблема понимания того, к какому именно then относится данный else, обычно такая проблема возникает в случае, если количество else не равно количеству then (если эти количества равны, то понять что во что вложено не трудно).
Рассмотрим пример (фрагмент кода), в котором есть подвох:
if (a > b) then if (a > c) then writeln('переменная а самая большая!') else // подразумеваем, что работает когда a<=b writeln('переменная a не больше b');
-- данный код отформатирован неверно, ведь он как бы показывает что else относится к первому then, в то время как Паскаль будет считать (всегда), что else относится к ближайшему then (не "отделённому" от этого else операторными скобками), итак, повторим эту идею ещё раз, назовём её правило "прикрепления" else:
В случае если число else не равно числу then (а это может быть только при вложенных блоках), else всегда "прикрепляется" (относится) к ближайшему "не изолированному" от него операторными скобками then.
Исходя из этого правила можно понять, что написанный выше код на самом деле имеет структуру:
if (a > b) then if (a > c) then writeln('переменная а самая большая!') else // !оказывается сработает если: c >= a >= b writeln('переменная a не больше b'); // значит это высказывание неверно!
-- но это значит, что уже неверна логика решения, из за того что на деле при подобной записи else относится к ближайшему then (мы показали это правильным форматированием и комментариями).
Но как же нам добиться задуманного в начале, т.е. той ситуации, когда в случае если a > b не верно, мы получили бы сообщение ""переменная a не больше b""?
Для этого нам придётся отделить ближайший then от else операторными скобками, то есть сделать так:
if (a > b) then begin if (a > c) then writeln('переменная а самая большая!') end else // работает когда a<=b writeln('переменная a не больше b');
Теперь ближайшим не изолированным операторными скобками от else словом then оказывается первое (то, где "if (a > b)"), а не второе (т.е. не то, где "if (a > c)") -- что мы и хотели изначально запрограммировать ;)
Видео-пояснения
Для этого урока есть следующие видео:
Самостоятельная работа
Вопросы
- Для чего нужен оператор ветвления (условный оператор)?
- Какие ветви условного оператора вы знаете?
- Чем полная форма условного оператора отличается от неполной?
- Когда нужны операторные скобки в ветвях оператора IF, а когда нет?
Задачи
- Сравните два числа, если первое больше второго, то выведите на экран "12". (здесь нужно использовать неполную форму условного оператора)
- Сравните два числа, если первое больше второго, то выведите на экран "12", а если нет, то выведите на экран "888".
- Даны три целых числа: $A$, $B$, $C$. Проверить истинность высказывания: «Число $A$ находится между числами $B$ и $C$» -- выведите "да", если истинно и "нет" если ложно.
ПРИМЕЧАНИЕ: эта следующая задача базируются на том, что мы уже решали (см. задачи в конце урока).
- Даны три целых числа: $A$, $B$, $C$. Проверить истинность высказывания: « Число $A$ и число $B$ больше 17, а $C$ > 7». -- выведите "да", если истинно и "нет" если ложно.
- Пользователь вводит два числа, найдите из них максимальное. (тут всё просто)
- Пользователь вводит три числа, найдите из них максимальное.
Решите тремя способами:
- С использованием логической операции and.
- С вложенными блоками (без and).
- Без вложенных блоков (без and) -- запомнив максимум из двух в специальной переменной.
Указание: Сначала посрайтесь написать все три решения самостоятельно (по 20 минут размышления на каждую задачу хотя бы), если не получается (или после решения) также можно посмотреть это видео-пояснение.
- Пользователь вводит четыре числа, найдите из них максимальное.
- Коля набрал $k$ баллов, Миша $n$ баллов, а Петя $d$ баллов в ходе соревнований. Если:
- сумма баллов Коли и Миши больше $20$
- или произведение баллов Пети и Миши меньше $55$
--то тогда вывести в консоль сообщение о том, что ничья, в противном случае вывести сообщение, что победил Коля.
Источники (что ещё почитать)
- Урок 8. Блок-схема оператора if: http://learnpascal.ru/operator-if/blok-s...
- Log in to post comments
- 31433 reads