Delphi-int.ru: портал программистов

Вход Регистрация | Забыли пароль?

События

Сегодня:
Вопросы0    Ответы0    Мини-форумы0


Последние:
Вопрос09.08, 09:39 / #6696
Ответ29.03, 23:32 / #6682
Новости8 июля 2023


Сейчас онлайн:
На сайте — 8
На IRC-канале — 2

Ссылки
Автор:
Ерёмин Андрей
Ошибаться человеку свойственно, но сваливать ошибки на других - еще типичнее.
Номер урока:
10
 

Логические выражения - тема сравнительно небольшая, но очень важная. Логические выражения встречаются практически в каждой программе. Понять принцип их работы очень важно, чтобы при написании программ не возникало трудностей с проверкой каких-либо данных.

Логический тип данных

С логическим типом данных мы уже неоднократно встречались при изучении свойств объектов. Этот тип данных состоит всего из двух значений: истина и ложь. На языке 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 (если включить эту опцию, то выражения будут вычисляться полностью).

Функция оптимизации логических выражений (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.

Небольшое замечание

Следует обратить внимание ещё вот на что. Если в выражении несколько операндов, то их следует брать в скобки, расставляя таким образом приоритеты выполнения. Если этого не сделать, результат может получиться иным. Примеры находятся в тесте, который расположен ниже.

Тест по теме
Для прохождения этого теста в Вашем браузере должен быть включен JavaScript. В почтовых программах тест работать не будет - нужно открыть его в браузере.
Определите значения приведённых логических выражений
True False

a:=True;
b:=False;

(a OR b) AND (a XOR b) = ?

True False

a:=False;
b:=True;
c:=False;

(NOT(b AND c) XOR (a OR c)) AND NOT(A) = ?

True False

a:=True;
b:=True;
c:=False;

NOT(NOT(a) OR NOT(b)) AND NOT(((A XOR B) OR (A OR B)) AND NOT(C)) = ?

Автор: Ерёмин А.А.

Статья добавлена: 19 июня 2007

Следующая статья: Обучающий курс. 11. События »

Рейтинг статьи: 4.79 Голосов: 14 Ваша оценка:

Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.


Статьи, похожие по тематике

 

Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

Ссылка для форумов (BBCode):

Быстрая вставка ссылки на статью в сообщениях на сайте:
{{a:110}} (буква a — латинская) — только адрес статьи (URL);
{{статья:110}} — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

Поделитесь ссылкой в социальных сетях:


Комментарии читателей к данной статье

D I M I C H I
Репутация: нет

D I M I C H I (5 декабря 2009, 18:17):

Ну с двумя значениями понятно, а как использовать XOR с 5 и более значениями? И какого типа они должны быть (у меня используются Integer i char(одновременно))?

Не пой му, че неработает:

k:=(CHR(02) xor CHR(strtoint(RadioGroup1.Items.Strings[RadioGroup1.itemindex])) xor p2 xor p3 xor CHR(03));


По отдельности в мемо выводит их, а формула кричит:

[Error] Unit1.pas(155): Operator not applicable to this operand type

а указатель ставит сразу после второго XOR'a. ПАМАХИТЕ!
weresk
Репутация: нет

weresk (25 мая 2009, 22:52):

Я только ещЁ собираю соответствующую литературу,но Ваше оформление мне уже нравится.Вот если бы Вы научили меня,как правильно с Вами общаться.
Николай Рубан
Репутация: +6

Николай Рубан (29 октября 2007, 23:55):

Считаю, что данную статью необходимо еще доработать...
Хотябы рассказать больше о работе с псевдослучайными числами, а именно о функциях которые позволяют вывести числа из заданного интервала, либо привести пример собственной аналогичной функции. ;)
Good Luck!!!

Оставлять комментарии к статьям могут только зарегистрированные пользователи.