Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
|
bb:redbook:109 [2017/08/30 15:25] prospero78 [3. Ключевое слово IF] |
— (текущий) |
===== 1.9 Введение в условия ===== | |
| |
==== 1. Определение условия ==== | |
//Условием// называется //любой// выбор, который //влияет// на ход дальнейших действий. Для человека каждую долю секунды приходится делать выбор: повернуть направо, посмотреть на светофор, передвинуть ногу чуть левее мимо лужи, переместить палец над нужной клавишей и т. д. //Условий// в повседневной деятельности столько, что было бы странно, если бы условий не было в языках программирования. И на самом деле, программирование //будет бесполезным//, если //логика программ будет прямой как палка//. | |
==== 2. Как работают условия в программировании ==== | |
Общий принцип работы условий одинаков во всех языках программирования, даже независимо от архитектуры компьютера, на столько это фундаментальная идея. При принятии решения в условиях используются всего два значения типа ''BOOLEAN'' — ''FALSE'' ("ложь") и ''TRUE'' ("истина"). Этих двух значений оказывается достаточно, чтобы описать любые формы условий. | |
==== 3. Ключевое слово IF ==== | |
Поскольку ''IF'' является //ключевым// словом, точно также, как и другие ключевые слова оно набирается заглавными буквами. Но здесь есть некоторые особенности. Когда языки программирования только оформлялись, никто не мог сказать точно, каким же образом описывать такие конструкции. Позже в языках **Си** и **python** были применены более короткие варианты ключевого слова ''IF'', но если в ''python'' это сделано лаконично (приравнивание использует ''='', а сравнение ''==''; использование присваиваний в условиях запрещено; очень похоже на то, как сделано в **КП**), то в **Си** это сделано просто короче, да ещё и с потерей наглядности (вплоть до //полной нечитаемости//, из-за того, что знак ''='' используется и в //присвоениях//, и в //сравнении//, что //неизбежно// приводит к трудноуловимым ошибкам; можно сказать, что у **Си** — //ошибка проектирования//). Поэтому, с учётом направленности **КП** на надёжность, его форму представления условий можно назвать //компромиссом// между лаконичностью и понимаемостью с небольшим уклоном в сторону понимаемости. | |
| |
Ниже представлен простейший пример условия в двух формах, выполняющий одно и тоже: | |
| |
> IF цПерем1=цПерем2 THEN цПерем1:=цПерем+1 END; | |
| |
В этом примере проверяется равенство значений двух переменных, и если они равны, первая переменная увеличивает своё значение на 1. В конце примера указано ключевое слово ''END'' — оно обязательно для ограничения условия. Почти во всех языках есть лексическое понятие для ограничения условия. В **python**, где нет ключевого слова ''END'', есть //уровневый отступ//, а в **Си** — фигурные скобки ''{ }''. В приведённом примере, после сравнения впервые использовано ключевое слово ''THEN'' ("тогда"), что если переписать на русском языке будет выглядеть примерно так: | |
| |
> ЕСЛИ цПерем1=цПерем2 ТОГДА цПерем1:=цПерем1+1 КОНЕЦ; | |
| |
Не правда ли, очень похоже на обыкновенную человеческую речь? Обратите внимание, что когда используется сравнение, то стоит простой знак //равно//, что является математически верной записью. Это как раз именно потому, что присваивание и сравнение в **Си** — слабо различимо. В этом отношении, **python** поступает более грамотно чем **Си**: в условиях используется знак ''=='', что не является математически правильной записью, но похоже на две половинки моста, которые пытаются свести вместе. Подход применённый в **python** пригоден при //начальном обучении программированию в школе//, но не //с точки зрения учёного//. | |
| |
Эту же условную конструкцию можно записать и в другом виде, но точно также правильном, с точки зрения компилятора **КП**: | |
| |
> IF цПерем1= цПерем2 THEN | |
> цПерем1:= цПерем1 + 1 | |
> END; | |
| |
В отличии от текста модулей и процедур здесь не нужно писать ключевое слово ''BEGIN''. Его роль, если хотите, выполняет ключевое слово ''THEN'' (оно завершает список условий). Точно также не нужно после последней инструкции в блоке ставить точку с запятой, так как далее следует ''END;''. | |
| |
Что будет если вдруг окажется, что ''цПерем1'' и ''цПерем2'' не равны? А ничего не будет. Действие после ''THEN'' будет проигнорировано, и программа продолжит своё выполнение после ''END;'' | |
==== 4. Ключевое слово ELSE ==== | |
''ELSE'' означает на английском ''ИНАЧЕ''. Это ключевое слово часто бывает нужно, если у условия есть альтернативное действие. Ниже приведён фрагмент, в котором реализовано условие с альтернативой только через ''IF'' и через ''ELSE'': | |
| |
> IF p1 = p2 THEN | |
> p1 := p1 + 1 | |
> END; | |
> | |
> IF p1 # p2 THEN | |
> p1 := p1 - 1 | |
> END; | |
| |
..............<skip>.............. | |
| |
> IF p1 = p2 THEN | |
> p1 := p1 + 1 | |
> ELSE | |
> p1 := p1 - 1 | |
> END; | |
| |
В первом фрагменте при использовании только ''IF'' пришлось записать два условия: | |
| |
1. когда ''р1'' равно ''р2'' | |
2. когда ''р1'' не равно ''р2'' (для этого использован оператор ''#'' — "решётка", "не равно", похожий на знак ≠) | |
| |
Если не использовать второе условие, то невозможно избежать после первого ''IF'' инструкции ''p1 := p1-1'', и тогда, в конечном итоге, это будет всё-равно, что и ''p1 := p1'', а в такой инструкции смысла нет никакого. | |
| |
При условии, в котором использован ''ELSE'' не пришлось повторно записывать условие ''IF'', так как не может быть, чтобы два числа были одновременно и равны друг другу, и не равны друг другу. Запись стала проще и понятней. | |
| |
Ещё раз обратите внимание на знак "не равно" — ''#''. В языке программирования **Си** используется знак ''!=''. В каком-то смысле похоже на ладонь, которая что-то останавливает. В **python** сейчас принято использовать такое же обозначение "не равно", но и до сих пор употребляется знак ''<>''. Ни первое, ни второе обозначение не является удачным. Какое отношение имеет ладонь останавливающая часть моста(кулака) к понятию //математического неравенства//? (да и можно ли ладонью остановить кулак?) Какое отношение к неравенству имеет сомнительный знак одновременно — //и больше и меньше//? Гораздо ближе к правде подходит //решётка//, как одна половинка моста, //не совмещённая// со второй половинкой моста (под углом 90 градусов), либо это //дважды перечёркнутый знак равенства//. Это //не математическая запись//, но более хорошо //понимаемая//, с точки зрения графического символа. Это всё элементы //промышленной надёжности// в **Компонентном Паскале**. | |
==== 5. Ключевое слово ELSIF ==== | |
Это ключевое слово частенько бывает необходимо, когда по условию, нужно выяснить, что например, переменная попадает в какой-то числовой или литеральный диапазон или равно чему-то конкретно более двух раз (при двух разах хватило бы одного ''ELSE''). Причём именно //такая// форма записи довольно эффективно обрабатывается компьютером, и если выполнена хотя бы одна ветка таких условий — остальные игнорируются. Пример такой конструкции дан ниже: | |
| |
<code oberon2> | |
IF p1 = p2 THEN | |
p1 := p1 + 1 | |
ELSIF p1 > p2 THEN | |
p1 := p1 - 1 | |
ELSIF p1 > (p2 - 2) THEN | |
p1 := p1 - 2 | |
ELSIF p1 > (p2 - 3) THEN | |
p1 := p1 - 3 | |
ELSE | |
p1 := p1 - 10 | |
END; | |
</code> | |
| |
После последней ветки есть необязательная конструкция ''ELSE''. Она будет выполнена //только тогда//, когда не выполнена //ни одна// из предыдущих веток. Также здесь впервые применён знак "больше" — ''>''. Также в условиях можно использовать знак "меньше" — ''<''. Знак сравнения всегда относится к той переменной, которая стоит //слева от знака сравнения//, т. е.: | |
| |
- "р1 равно р2" — ''p1 = p2''; | |
- "р1 меньше р2" — ''p1 < p2''; | |
- "р1 больше р2" — ''p2 > p2'' и т. д. | |
| |
==== 6. Составные условия ==== | |
Условие является составным, если в сравнении участвует более двух переменных, пример такого условия: | |
<code oberon2> | |
IF (p1 > p2) & (p1 > 10) THEN | |
p1 := p1 + 1 | |
ELSIF (p1 > p2) AND (p2 < 0) THEN | |
p1 := p1 - 1 | |
ELSE | |
p1 := p1 - 10 | |
END; | |
</code> | |
| |
В первом условии использовано ''ЛОГИЧЕСКОЕ И'' — ''&'' ("амперсанд"). Оно соответствует логическому умножению. В сумме первое условие читается так: если _переменная ''р1'' больше переменной ''р2''_ И _переменная р1 больше 10 ТО_ .... и далее действия, которые определены в этой ветке. Во второй ветке условие читается так: если ''р1'' больше ''р2 И р2'' меньше нуля ''ТО''... и далее действия, которые определены именно для этой ветки. | |
| |
Существует несколько видов связок для составных условий: | |
| |
- & — логическое И | |
- ~ — логическое отрицание | |
- OR — логическое ИЛИ | |
| |
Все эти операции можно комбинировать любым доступным способом, помня о том, что в **Компонентном Паскале** поддерживаются математические приоритеты. | |
==== 7. Простые условия ==== | |
| |
Простые условия, это такие условия, в которых результат логических вычислений присваивается только одной булевой переменной. Иногда встречается определение линейное условие, которое тоже вполне правильное. Название простые условия не должно вводить в заблуждение: само условие может быть весьма сложным. Простые условия можно записывать в следующей форме: | |
<code oberon2> | |
VAR | |
b1, b2: BOOLEAN; | |
BEGIN | |
b1:= (p1 > p2) & (p1 > 10); | |
b2:= (p1 > p2) AND (p2 < 0); | |
| |
IF b1 THEN | |
p1 := p1 + 1 | |
ELSIF b2 THEN | |
p1 := p1 - 1 | |
ELSE | |
p1 := p1 - 10 | |
END; | |
END; | |
</code> | |
Здесь происходит предварительное вычисление выражений для булевых переменных ''b1'' и ''b2''. И в зависимости от полученных результатов (''TRUE'' или ''FALSE'') — дальше будет выполняться (или не выполняться) ветка условия. Такой приём может быть удобен, если результаты таких логических вычислений будут использоваться более одного раза — это ускорит выполнение программы, и главное — упростит её понимание. | |
| |
| |
==== 8. Заключение ==== | |
По большому счёту, имея эти знания по //условиям// можно перекрыть 95% потребностей в логике программы. Есть и более сложные условия, с которыми можно столкнуться в реальной жизни, ведь сложность программных систем очень велика, и как показывает анализ машинного кода — около 20% всего кода приходится на проверку условий. | |