5.7 – Логические операторы
Хотя операторы отношения (сравнения) могут использоваться для проверки того, является ли конкретное условие истинным или ложным, они могут проверять только одно условие за раз. Но часто нам нужно знать, выполняются ли одновременно несколько условий. Например, чтобы проверить, выиграли ли мы в лотерею, мы должны сравнить, все ли выбранные нами числа совпадают с выигрышными числами. В лотерее с 6 числами это будет включать 6 сравнений, и все они должны быть верными. В других случаях нам нужно знать, выполняется ли какое-либо из нескольких условий. Например, мы можем решить пропустить работу сегодня, если мы заболели, или если мы слишком устали, или если мы выиграли в лотерею в нашем предыдущем примере. Это потребует проверки того, верно ли какое-либо из трех сравнений.
Возможность тестирования несколько условий нам дают логические операторы.
В C++ есть 3 логических оператора:
Оператор | Обозначение | Пример использования | Операция |
---|---|---|---|
Логическое НЕ (NOT) | ! | !x | true , если x равен false ; или false , если x равен true |
Логическое И (AND) | && | x && y | true , если и x ,и y равны true ; в противном случае – false |
Логическое ИЛИ (OR) | || | x || y | true , если x или y равен true ; в противном случае – false |
Логическое НЕ (NOT)
Вы уже сталкивались с унарным оператором логического НЕ в уроке «4.9 – Логические (булевы) значения». Мы можем резюмировать эффекты логического НЕ следующим образом:
Операнд | Результат |
---|---|
true | false |
false | true |
Если операнд логического НЕ вычисляется как true , логическое НЕ вычисляется как false . Если операнд логического НЕ вычисляется как false , логическое НЕ вычисляется как true . Другими словами, логическое НЕ меняет логическое значение с true на false и наоборот.
Логическое НЕ часто используется в условных выражениях:
Следует остерегаться того, что логическое НЕ имеет очень высокий уровень приоритета. Начинающие программисты часто делают следующую ошибку:
Эта программа напечатает:
Но x не больше y , так как же это возможно? Ответ заключается в том, что поскольку оператор логического НЕ имеет более высокий приоритет, чем оператор «больше чем», выражение !x > y фактически вычисляется как (!x) > y . Поскольку x равно 5, !x вычисляется как 0, а 0 > y равно false , поэтому выполняется инструкция else !
Правильный способ написать приведенный выше фрагмент:
Таким образом, сначала будет вычислено x > y , а затем логическое НЕ инвертирует логический результат.
Лучшая практика
Если логическое НЕ предназначено для работы с результатом других операторов, другие операторы и их операнды должны быть заключены в круглые скобки.
Простое использование логического НЕ, например if (!value) , не требует скобок, потому что приоритет здесь не играет роли.
Логическое ИЛИ (OR)
Оператор логического ИЛИ используется для проверки того, выполняется ли одно из двух условий. Если значение левого операнда истинно, или значение правого операнда истинно, или оба значения истинны, то логический оператор ИЛИ возвращает true . В противном случае он вернет false .
Левый операнд | Правый операнд | Результат |
---|---|---|
false | false | false |
false | true | true |
true | false | true |
true | true | true |
Например, рассмотрим следующую программу:
В этом случае мы используем логический оператор ИЛИ, чтобы проверить, истинно ли левое условие ( value == 0 ) или правое условие ( value == 1 ). Если одно из них (или оба) истинны, логический оператор ИЛИ принимает значение true , что означает выполнение инструкции if . Если ни одно из них не является истинным, результат логического оператора ИЛИ будет false , что означает выполнение инструкции else .
Вы можете связать вместе множество операторов логического ИЛИ:
Начинающие программисты иногда путают оператор логическое ИЛИ ( || ) с оператором побитовое ИЛИ ( | ) (который будет рассмотрен позже). Несмотря на то, что у них обоих в названии есть «ИЛИ», они выполняют разные функции. Их смешивание, вероятно, приведет к неверным результатам.
Логическое И (AND)
Логический оператор И используется для проверки истинности обоих операндов. Если оба операнда равны true , логическое И возвращает true . В противном случае возвращается false .
Левый операнд | Правый операнд | Результат |
---|---|---|
false | false | false |
false | true | false |
true | false | false |
true | true | true |
Например, нам может потребоваться узнать, находится ли значение переменной x в диапазоне от 10 до 20. На самом деле это два условия: нам нужно знать, больше ли x , чем 10, а также меньше ли x , чем 20.
В этом случае мы используем оператор логическое И, чтобы проверить, истинны ли левое условие ( value > 10 ) и правое условие ( value < 20 ). Если оба условия истинны, оператор логическое И принимает значение true , и выполняется инструкция if . Если ни одно из условий или хотя бы одно из них не соответствует истине, оператор логическое И принимает значение false , и выполняется инструкция else .
Как и в случае с логическим ИЛИ, вы можете связать вместе множество операторов логическое И:
Если все эти условия верны, будет выполнена инструкция if . Если какое-либо из этих условий ложно, будет выполняться инструкция else .
Вычисление по короткой схеме
Чтобы логическое И возвращало true , оба операнда должны иметь значение true . Если первый операнд вычисляется как false , логическое И знает, что оно должно возвращать false , независимо от того, вычисляется ли второй операнд как true или false . В этом случае оператор логическое И немедленно вернет false , даже не вычисляя второй операнд! Это известно как вычисление по короткой схеме и выполняется в основном в целях оптимизации.
Точно так же, если первый операнд для логического ИЛИ равен true , тогда всё условие ИЛИ должно вычисляться как true , и второй операнд не вычисляется.
Вычисление по короткой схеме дает еще одну возможность показать, почему операторы, вызывающие побочные эффекты, не должны использоваться в составных выражениях. Рассмотрим следующий фрагмент:
Если x не равно 1, всё условие должно быть ложным, поэтому ++y никогда не вычисляется! Таким образом, y будет инкрементироваться только в том случае, если x равен 1, что, вероятно, не совсем то, что задумывал программист!
Предупреждение
Вычисление по короткой схеме может привести к тому, что логическое ИЛИ и логическое И не будут вычислять один операнд. Избегайте использования выражений с побочными эффектами в выражениях с этими операторами.
Как и в случае с логическим и побитовым ИЛИ, начинающие программисты иногда путают оператор логическое И ( && ) с оператором побитовое И ( & ).
Смешивание И и ИЛИ
Смешивания операторов логическое И и логическое ИЛИ в одном выражении часто невозможно избежать, но это область, полная потенциальных опасностей.
Многие программисты предполагают, что логическое И и логическое ИЛИ имеют одинаковый приоритет (или забывают, что это не так), точно так же, как сложение/вычитание и умножение/деление. Однако логическое И имеет более высокий приоритет, чем логическое ИЛИ, поэтому операторы логическое И будут вычисляться перед операторами логическое ИЛИ (если они не заключены в скобки).
Начинающие программисты часто пишут такие выражения, как value1 || value2 && value3 . Поскольку логическое И имеет более высокий приоритет, это выражение вычисляется как value1 || (value2 && value3) , а не как (value1 || value2) && value3 . Надеюсь, это то, чего хотел программист! Если программист предполагал вычисление слева направо (как это происходит со сложением/вычитанием или умножением/делением), он или она получит не тот результат, который не ожидался!
При смешивании логического И и логического ИЛИ в одном выражении рекомендуется явно заключать в скобки каждый оператор и его операнды. Это помогает предотвратить ошибки приоритета, упрощает чтение кода и четко определяет, как вы рассчитывали вычислять выражение. Например, вместо записи value1 && value2 || value3 && value4 , лучше написать (value1 && value2) || (value3 && value4) .
Лучшая практика
При смешивании логического И и логического ИЛИ в одном выражении явно заключите каждую операцию в скобки, чтобы убедиться, что они вычисляются так, как вы хотите.
Закон де Моргана
Многие программисты также ошибаются, полагая, что !(x && y) – это то же самое, что !x && !y . К сожалению, так нельзя «распределять» логическое НЕ.
Закон де Моргана говорит нам, как логическое НЕ должно распределяться в этих случаях:
Другими словами, когда вы распределяете логическое НЕ, вам также необходимо преобразовать логическое И в логическое ИЛИ, и наоборот!
Иногда это может быть полезно при попытке упростить чтение сложных выражений.
Где логический оператор исключающее ИЛИ (XOR)?
Логический оператор исключающее ИЛИ (XOR) – это логический оператор, представленный на некоторых языках, который используется для проверки истинности нечетного числа условий.
Левый операнд | Правый операнд | Результат |
---|---|---|
false | false | false |
false | true | true |
true | false | true |
true | true | false |
В C++ нет оператора л огическое исключающее ИЛИ . В отличие от логического ИЛИ или логического И, логическое исключающее ИЛИ не может быть вычислено по короткой схеме. По этой причине создание оператора логическое исключающее ИЛИ из операторов логического ИЛИ и логического И является сложной задачей. Однако вы можете легко имитировать логическое исключающее ИЛИ (XOR), используя оператор неравенства ( != ):
Это выражение можно расширить до нескольких операндов следующим образом:
Обратите внимание, что приведенные выше шаблоны логического исключающего ИЛИ работают только в том случае, если операнды являются логического типа (не целочисленными значениями). Если вам нужна форма логического исключающего ИЛИ, которая работает с не-логическими операндами, вы можете использовать static_cast для преобразования их в bool :
Небольшой тест
Вопрос 1
Вычислите следующие выражения.
Примечание: в ответах мы «объясняем нашу работу», показывая вам шаги, предпринятые для получения окончательного ответа. Шаги разделены символом →. Выражения, которые были проигнорированы из-за правила вычисления по короткой схеме, помещены в квадратные скобки. Например,
означает, что мы вычислили (1 <2 || 3 != 3) , чтобы прийти к (true || [3 != 3]) , и вычислили его, чтобы прийти к true . 3 != 3 никогда не выполнялся из-за вычисления по короткой схеме.
a) (true && true) || false
b) (false && true) || true
Вычисление по короткой схеме имеет место быть, если первый операнд || равен true .
Что значит или в информатике
2) Логическое сложение или дизъюнкция:
Дизъюнкция — это сложное логическое выражение, которое истинно, если хотя бы одно из простых логических выражений истинно и ложно тогда и только тогда, когда оба простых логических выраженbя ложны.
Обозначение: F = A v B.
Таблица истинности для дизъюнкции
A | B | F |
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
3) Логическое отрицание или инверсия:
Инверсия — это сложное логическое выражение, если исходное логическое выражение истинно, то результат отрицания будет ложным, и наоборот, если исходное логическое выражение ложно, то результат отрицания будет истинным. Другими простыми слова, данная операция означает, что к исходному логическому выражению добавляется частица НЕ или слова НЕВЕРНО, ЧТО.
Обозначение: F = ¬ A.
Таблица истинности для инверсии
A | ¬ А |
1 | 0 |
0 | 1 |
4) Логическое следование или импликация:
Импликация — это сложное логическое выражение, которое истинно во всех случаях, кроме как из истины следует ложь. То есть данная логическая операция связывает два простых логических выражения, из которых первое является условием (А), а второе (В) является следствием.
«A → B» истинно, если из А может следовать B.
Обозначение: F = A → B.
Таблица истинности для импликации
A | B | F |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 1 |
0 | 0 | 1 |
5) Логическая равнозначность или эквивалентность:
Эквивалентность — это сложное логическое выражение, которое является истинным тогда и только тогда, когда оба простых логических выражения имеют одинаковую истинность.
A | B | F |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 1 |
6) Операция XOR (исключающие или)
Обозначение: F = A ⊕ B .
A | B | F |
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
Порядок выполнения логических операций в сложном логическом выражении
1. Инверсия;
2. Конъюнкция;
3. Дизъюнкция;
4. Импликация;
5. Эквивалентность.
Для изменения указанного порядка выполнения логических операций используются скобки.
Таблицы истинности можно составить и для произвольной логической функции F(a, b, c…).
В общем случае таблицы истинности имеют размер 2 N строк комбинаций для N независимых логических переменных.
Законы алгебры логики
Те, кому лень учить эти законы, должны вспомнить алгебру, где знание нескольких способов преобразования позволяет решать очень сложные уравнения.
Строго говоря, это не законы, а теоремы. Но их доказательство не входит в программу изучения. Впрочем, доказательство обычно основывается на построении полной таблицы истинности.
Замечание. Знаки алгебры логики намеренно заменены на сложение и умножение.
Замена операций импликации и эквивалентности
Операций импликации и эквивалентности иногда нет среди логических операций конкретного компьютера или транслятора с языка программирования. Однако для решения многих задач эти операции необходимы. Существуют правила замены данных операций на последовательности операций отрицания, дизъюнкции и конъюнкции.
Так, заменить операцию импликации можно в соответствии со следующим правилом:
A → B = ¬ A \/ B
Для замены операции эквивалентности существует два правила:
В справедливости данных формул легко убедиться, построив таблицы истинности для правой и левой частей обоих тождеств.
Логические основы работы компьютера
Знания из области математической логики можно использовать для конструирования электронных устройств. Нам известно, что 0 и 1 в логике не просто цифры, а обозначение состояний какого-то предмета нашего мира, условно называемых «ложь» и «истина». Таким предметом, имеющим два фиксированных состояния, может быть электрический ток.
Логические элементы имеют один или несколько входов и один выход, через которые проходят электрические сигналы, обозначаемые условно 0, если «отсутствует» электрический сигнал, и 1, если «имеется» электрический сигнал.
Базовые логические элементы реализуют три основные логические операции: «И», «ИЛИ», «НЕ».
Логический элемент «НЕ» (инвертор)
Простейшим логическим элементом является инвертор, выполняющий функцию отрицания. Если на вход поступает сигнал, соответствующий 1, то на выходе будет 0. И наоборот.
У этого элемента один вход и один выход. На функциональных схемах он обозначается:
Говорят также, что элемент «НЕ» инвертирует значение входной двоичной переменной.
Проверь соответствие логического элемента «НЕ» логическому элементу «НЕ». Воспользуйся тренажером Логические элементы.xlsx
Логический элемент «И» (конъюнктор)
Логический элемент «И» (конъюнктор) выдает на выходе значение логического произведения входных сигналов.
Он имеет один выход и не менее двух входов. На функциональных схемах он обозначается:
Сигнал на выходе конъюнктора появляется тогда и только тогда, когда поданы сигналы на все входы. На элементарном уровне конъюнкцию можно представить себе в виде последовательно соединенных выключателей. Известным примером последовательного соединения проводников является елочная гирлянда: она горит, когда все лампочки исправны. Если же хотя бы одна из лампочек перегорела, то гирлянда не работает.
Проверь соответствие логического элемента «И» логическому элементу «И». Воспользуйся тренажером Логические элементы.xlsx
Логический элемент «ИЛИ» (дизъюнктор)
Логический элемент «ИЛИ» (дизъюнктор) выдает на выходе значение логической суммы входных сигналов. Он имеет один выход и не менее двух входов. На функциональных схемах он обозначается:
Сигнал на выходе дизъюнктора не появляется тогда и только тогда, когда на все входы не поданы сигналы.
На элементарном уровне дизъюнкцию можно представить себе в виде параллельно соединенных выключателей.
Примером параллельного соединения проводников является многорожковая люстра: она не работает только в том случае, если перегорели все лампочки сразу.
Проверь соответствие логического элемента «ИЛИ» логическому элементу «ИЛИ». Воспользуйся тренажером Логические элементы.xlsx
Пример 1.
Составьте логическую схему для логического выражения: F=A \/ B /\ A.
1. Две переменные – А и В.
2. Две логические операции: 1-/\, 2-\/.
Пример 2.
Постройте логическую схему, соответствующую логическому выражению F=А/\В\/ ¬(В\/А). Вычислить значения выражения для А=1,В=0.
1. Переменных две: А и В; 1 4 3 2
2. Логических операций три: /\ и две \/; А/\В\/ ¬ (В\/ А).
3. Схему строим слева направо в соответствии с порядком логических операций:
Логические элементы «И», «ИЛИ», «НЕ»
Логические элементы «И», «ИЛИ», «НЕ» — это предназначенные для обработки цифровой информации (сигналов) элементы, обеспечивающие формирование выходного сигнала путем вычисления соответствующей логической функции для входного сигнала.
Электронные логические схемы нашли широкое применение в устройствах, оперирующих двумя состояниями. Система, работающая с двумя состояниями, предполагает два уровня:
- «включено» и «выключено»,
- «вверх» и «вниз»,
- «да» и «нет»,
- «высокий уровень сигнала» и «низкий уровень сигнала».
Логическими (цифровыми) схемами называют тип электронных схем, работающих с двумя уровнями напряжения, что позволяет пользоваться алгеброй логики (введя обозначения для уровней напряжения 0 и 1).
Логические схемы – это ключевой компонент современных электронных устройств. Благодаря тому, что цифровые схемы малочувствительны к помехам, их использование позволяет добиться лучших результатов при меньшей интенсивности отказов.
Применение логических элементов и алгебры логики позволяет проектировать и разрабатывать разнообразные системы, например:
- цифровые радиоприемники,
- калькуляторы,
- системы сигнализации,
- компьютеры,
- смартфоны.
Логические схемы строятся на логических элементах. В разных схемах используются разные наборы элементов, но элементы «И», «ИЛИ», «НЕ» являются общепризнанным базисным набором. Булевы функции, по которым строятся логические схемы, могут быть рассмотрены как математическая модель такой схемы.
По сути логический элемент является электрической схемой, обеспечивающей выполнение той или иной логической операции над входными данными. В качестве входных данных используется напряжение разного уровня. Результатом логической операции также является напряжение какого-либо уровня.
Итак, операндами выступают сигналы, подающиеся в двоичной системе счисления как напряжение высокого или низкого уровня. Обычно данные трактуют следующим образом:
- напряжение высокого уровня рассматривается как логическая единица (значение операнда «истина»),
- напряжение низкого уровня рассматривается как логический ноль (значение операнда «ложь»).
Логический элемент обеспечивает между входными и выходными сигналами логическую зависимость. Обычно логические элементы используют, чтобы построить:
- логические схемы в вычислительных машинах,
- дискретные схемы автоматизации управления (контроля).
Независимо от конкретной реализации и физической природы используемых сигналов, все виды логических элементов оперируют дискретными значениями.
Цифровые логические схемы делятся на две категории:
- комбинаторные (комбинационные), в которых выходной логический уровень определяется только текущими логическими уровнями на входе;
- последовательные, обладающие характеристикой памяти. В них выход определяется не только текущими входными условиями, но и имеющимся состоянием выхода (выходным сигналом).
Логический элемент является базовым строительным блоком для логических схем. Он выполняет логическую функцию. У логического элемента может быть один или несколько входов; выход, как правило, один (или пара инверсных). Значение на выходе логического элемента представляет собой функцию от входных сигналов. Используя всего три логических элемента «И», «ИЛИ», «НЕ» можно построить любую логическую схему.
Логические элементы реализуют логические функции.
Под логической функцией понимают функцию, возвращающую для конечного числа логических входных параметров логические значения.
Логическая функция может быть задана разными способами:
- словесным описанием,
- таблицей истинности,
- в виде логического уравнения (алгебраического выражения),
- графически с использованием логических символов.
Любая сложная логическая функция может быть составлена из элементарных логических функций.
Любой логический элемент может быть реализован путем подходящего соединения транзисторов, диодов, резисторов и других компонентов. В настоящее время дискретные логические элементы используются очень мало и заменяются логическими схемами более высокой степени интеграции, выполняющими более сложные логические функции. Однако эти функции по-прежнему реализуются из множества более простых схем. Цифровые схемы позволяют обрабатывать цифровые сигналы просто и в то же время очень быстро.
Элементарные логические элементы «И», «ИЛИ», «НЕ»
Логический элемент «НЕ», также называемый «инвертор», «отрицание», «NOT», выполняет над входными данными логическое отрицание. Этот элемент имеет один вход и один выход. На выходе получается инверсия входного сигнала:
- если на вход поступила истина, на выходе будет ложь;
- если на вход поступила ложь, на выходе будет истина.
Логический элемент «И», также называемый «конъюнктор», «логическое умножение», «AND», выполняет логическое сложение (конъюнкцию) входных данных. Количество входов у этого элемента может варьироваться (базовый вариант – 2 входа, но встречаются и трех-, четырех- и более входовые модификации), выход один. На выходе логического элемента «И» будет истина, если все входные сигналы соответствуют истине (в случае двухвходового конъюнктора – сигналы на первом и втором входе), во всех остальных случаях (если хотя бы на один из входов подана ложь) на выходе будет получена ложь.
Логический элемент «ИЛИ», также называемый «дизъюнктор», «логическое сложение», «OR», выполняет логическое сложение (дизъюнкцию) над входными данными. Аналогично конъюнктору, дизъюнктор может иметь два или более входов. Выход у дизъюнктора один. Значение истины на выходе появляется в том случае, если хотя бы на одном из логических входов есть истина. Ложь на выходе формируется только в том случае, если на все логические входы подается ложь.
Наряду с перечисленными базовыми логическими элементами достаточно часто используют другие логические элементы: