Логические выражения - тема сравнительно небольшая, но очень
важная. Логические выражения встречаются практически в каждой программе. Понять
принцип их работы очень важно, чтобы при написании программ не возникало
трудностей с проверкой каких-либо данных.
Логический тип данных
С логическим типом данных мы уже неоднократно встречались при
изучении свойств объектов. Этот тип данных состоит всего из двух значений:
истина и ложь. На языке Pascal (а также на
многих других языках) это соответственно True и False.
В некоторых языках допускается использование чисел вместо этих переменных:
1 - истина, 0 - соответственно ложь. Итак,
логический тип данных указывает, есть ли что-то или его нет, верно ли что-то или
неверно.
В Pascal логический тип данных носит название Boolean
(англ. - логический). Значения, как уже было сказано - True
и False. Простой пример объявления логической переменной и
присвоения ей значения "ложь":
var X: Boolean;
X:=False;
Операции над логическими выражениями
А вот и самое интересное. Для логических выражений введены 4
операции. Работа с ними чем-то похожа на работу с числами. Рассмотрим подробно
эти операции.
1. Отрицание: NOT
("не")
Как понятно из названия, данная операция меняет значение
логического выражения на противоположное: если была истина, то станет ложь, а
если была ложь, то станет истина. Выражение, над которым будет произведена
операция, указывается либо после слова NOT через пробел, либо в скобках.
Примеры:
k:=True;
m:=not(k);
n:=not m;
p:=not(not(m));
Подразумевается, что все переменные описаны типом данных
Boolean. Итак, разберём, что здесь происходит:
- Сначала мы присваиваем переменной k
значение True;
- Далее, выполняя NOT для k
получаем False: m становится равным False;
- n становится противоположным m,
т.е. True;
- Над m делается двойное отрицание, т.е.
значение p станет также False.
2. Логическое умножение (конъюнкция) - AND
("и")
В отличие от рассмотренного выше NOT, оператор
AND работает уже с двумя (и более) выражениями. Логическое
умножение равно истине тогда и только тогда, когда все выражения, связанные этим
оператором, истинны. Если хотя бы один является ложью, то весь результат будет
также ложью. Поэтому, собственно, операция и называется умножением: если истину
обозначить за 1, а ложь - за 0, а числа перемножить, то при наличии хотя бы
одного нуля весь результат будет нулевым. Примеры:
a:=True;
b:=False;
c:=True;
d:=a and b;
e:=a and c;
f:=not(b) and c;
Значение d будет False, т.к. один из
операндов (операнды - выражения, которыми управляют
операторы) равен False (b). Переменная e
примет значение True, ведь и a и c
истинны. Наконец, f тоже станет True, ведь
not(b) - это истина и c тоже истина.
3. Логическое сложение (дизъюнкция) - OR
("или")
Как и AND, OR работает с несколькими
операндами. Название "или" уже отвечает на вопрос "что будет в итоге": если хотя
бы один из операндов - истина, то всё выражение будет истиной. Результат
False будет только в случае, если все операнды будут ложными.
a:=False;
b:=True;
c:=a or b;
d:=not(b) or a;
Значение переменной c станет True, а
переменной d - False.
4. Исключающее "или" - XOR
Данная операция выдат результат True, если один из
операндов является истиной, а другой - ложью, т.е. выражения не должны быть
одинаковыми.
a:=True;
b:=False;
c:=a xor b;
d:=not(a) xor b;
e:=not(a) xor not(b);
Переменная c станет истиной, ведь a
и b различны, а d - ложью, т.к. под сравнение
попадут два значения False. Наконец, e станет истиной.
Итог
Этих четырёх операций - NOT, AND, OR,
XOR достаточно для построения логического выражения любой сложности.
Эти операторы могут как угодно комбинироваться и можно составлять большие
выражения. Однако следует заботиться и о скорости работы. Если выражение
вычисляется один раз - всё в норме, но если оно будет вычисляться несколько
тысяч раз (например, обработка информации из большой базы данных), то
грамотность составленного выражения будет отражаться на скорости выполнения
операции. Если в программе появились грмоздкие логические выражения, следует
задуматься об их упрощении: одно условие всегда будет проверяться быстрее, чем
два.
Немного об оптимизации
В Delphi есть специальные методы оптимизации, в том числе и
для логических выражений. Дело в том, что в некоторых случаях вычисление
логического выражения полностью не требуется, чтобы получить результат. Простые
примеры на AND и OR:
A:=False;
B:=True;
C:=True;
D:=True;
X:=A and B and C and D;
Поскольку используется оператор AND, результат всего
выражения будет истинным только в том случае, если все выражения будут истинны.
В данном же случае уже первое выражение (A) ложно. Дальнейшая
проверка просто не имеет смысла - всё равно результат останется False.
Ещё пример:
A:=True;
B:=False;
C:=True;
D:=False;
X:=A or B or C or D;
Абсолютно неважно, какие значения имеют B,
C и D, ведь A истинно, а
значит OR в любом случае выдаст True.
Изначально такая оптимизация в Delphi включена, т.е. выражения
не будут вычисляться полностью. Эту возможность можно отключить (правда,
непонятно - зачем?) в свойствах проекта: Project » Options » Compiler »
Complete boolean eval (если включить эту опцию, то выражения будут
вычисляться полностью).
Практическое применение
Где применяются логические выражения? Практически повсюду. Они
могут использовать лишь в программном коде для каких-либо проверок, а могут быть
связаны и с интерфейсом программы. Как уже было сказано ранее, многие свойства
компонент заданы логическим типом данных. Например, давайте сделаем две кнопки и
запрограммируем их так, чтобы на экране всегда была только одна. Помещаем на
форму 2 кнопки (TButton) и одну из них (Button2 например)
делаем невидимой: в Инспекторе Объектов изменяем свойство Visible на
False. Теперь дважды щёлкаем по Button1 и пишем (дописать
следует только то, что находится между begin и end):
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Visible:=False;
Button2.Visible:=not Button1.Visible;
end;
Разберёмся, что здесь происходит. Сначала мы изменяем
видимость 1-ой кнопки - скрываем её. А затем меняем видимость 2-ой кнопки на
противоложное первому. Аналогично пишем обработчик 2-ой кнопки:
procedure TForm1.Button2Click(Sender: TObject);
begin
Button2.Visible:=False;
Button1.Visible:=not Button2.Visible;
end;
Если теперь запустить программу и пощёлкать по кнопкам, то они
будут по очереди появляться на экране. В принципе, вторые строки обоих
обработчиков можно написать и немного иначе - просто присвоить другой кнопке
Visible:=True - результат не изменится. Такой способ приведён лишь в
качестве примера использования оператора NOT.
Небольшое замечание
Следует обратить внимание ещё вот на что. Если в выражении
несколько операндов, то их следует брать в скобки, расставляя таким образом
приоритеты выполнения. Если этого не сделать, результат может получиться иным.
Автор: Ерёмин Андрей
|