07 апреля 2020

Логические операции

    Рассмотренные в предыдущем параграфе операции сравнения используются в условном операторе if (о нем и других операторах Perl в следующей главе) для организации ветвления в программе. Однако, иногда желательно проверять одновременно результаты нескольких операций сравнения и предпринимать соответствующие алгоритму действия. Можно подобную ситуацию запрограммировать с помощью вложенных операторов if, а можно в одном операторе использовать сложное выражение, результатом вычисления которого будет, например, истинность двух или более каких-либо операций сравнения. Для формирования подобных проверок и служат логические операции языка Perl.
     В языке определены бинарные операции логического сравнения | 1 (ИЛИ), s & (И) и унарная операция логического отрицания !. Их действие аналогично действию соответствующих математических операций исчисления предикатов. Результатом операции | | (логическое ИЛИ) является Истина, если истинен хотя бы один из операндов, в остальных случаях она возвращает Ложь (остальные случаи представляют единственный вариант, когда оба операнда ложны). Операция логического И && возвращает в качестве результата Истину, только если оба операнда истинны, в противном случае ее результат Ложь. Операция логического отрицания ! работает как переключатель: если ее операнд истинен, то она возвращает Ложь, если операнд имеет значение Ложь, то ее результатом будет Истина.
Замечание
В языке Perl нет специальных литералов для булевых значений Истина и Ложь. В качестве значения Истина принимается любое скалярное значение, не равное нулевой строке "" или числу 0 (а также его строковому эквиваленту "О"). Естественно, нулевая "" строка и о (вместе с его строковым эквивалентом "О") представляют значение Ложь.
     Начиная с Perl 5.001, в язык были введены логические операции or, and, not и хог. Первые три полностью аналогичны логическим операциям | |, && и !, тогда как операция хог реализует исключающее ИЛИ:

Истина хоr Истина = Ложь
Истина хоr Ложь = Истина
Ложь хоr Истина = Истина
Ложь хоr Ложь = Ложь

      Единственное отличие этих логических операций от рассмотренных ранее заключается в том, что они имеют наименьший приоритет при вычислении сложных выражений.
     В Perl вычисление логических операций ИЛИ и И осуществляется по "укороченной схеме". Это непосредственно связано со смыслом этих операций. Если при вычислении операции ИЛИ определено, что значение ее первого операнда Истина, то при любом значении второго операнда результатом всей операции будет Истина, поэтому нет смысла вообще вычислять второй операнд. Аналогично для операции логического И: если значение первого операнда Ложь, то результат всей операции Ложь вне зависимости от значения второго операнда. В отличие от операций отношения, результатом которых может быть о (или пустая строка "") или 1, соответствующие булевым значениям Ложь и Истина, результатом логических операций является значение последнего вычисленного операнда. Пример 4.10 иллюстрирует вычисление логических операций.

$opl = 0; $ор2 = "s"; $орЗ = ""; $ор4 = 25; $ор5 = "0";
$ор4 II $ор2; # Результат: истина. Значение: 25.
$ор2 I| $ор4; # Результат: истина. Значение: "s".
$opl && $ор2; # Результат: ложь. Значение: 0.
$ор2 && $ор4; # Результат: истина. Значение: 25.
!$ор2; # Результат: ложь. Значение: "".
not $орЗ; # Результат: истина. Значение: 25.
$ор4 and $op5; # Результат: ложь. Значение: "".

      Свойство логических операций языка Perl вычисляться по "укороченной схеме" можно использовать для управления некоторыми исключительными ситуациями, возникающими в программе в процессе вычислений. Например, можно достаточно элегантно избежать деления на нуль с помощью операции логического ИЛИ:

($х = 0) II ($т = 1/$х);

      При вычислении результата этой операции сначала вычисляется левый операнд, который сравнивает значение переменной $х с нулем. Если это значение действительно равно нулю, то результатом операции сравнения будет Истина, а поэтому второй операнд операции логического ИЛИ не вычисляется, так его значение не влияет на результат выполнения логической oпeрации, и не возникает ситуации деления на нуль. Если значение переменной $х не равно нулю, то результатом вычисления первого операнда операции | | будет Ложь, и обязательно будет вычисляться ее второй операнд, в котором осуществляется деление на не равную нулю переменную $х.