Урок 43. Логические операторы (И, ИЛИ, НЕ)

   ⁄ 

 Обновлено 4 Мар 2017

  ⁄   

В то время как операторы сравнения используются для проверки конкретного условия, ложное оно или истинное, они могут проверить только одно условие за определенный промежуток времени. Но бывают ситуации, когда нужно протестировать сразу несколько условий. Например, чтобы узнать, выиграли ли мы в лотерею, нам нужно сравнить все цифры купленного билета с выигрышными. Если в лотерее 6 цифр, тогда нужно выполнить 6 сравнений, все из которых должны быть true.

Также иногда, нам нужно знать, является ли хоть одно из нескольких условий истинным. Например, мы не пойдем сегодня на работу, если больны или слишком устали, или если выиграли в лотерею 🙂 Нам нужно проверить, является ли хоть одно из этих 3 условий истинным. Как это сделать? С помощью логических операторов! Они позволяют проверить сразу несколько условий за раз. В C++ есть 3 логических оператора:

Оператор Символ Пример Операция
Логическое НЕ ! !x true, если x — false и false, если x — true
Логическое И && x && y true, если x и y — true, в противном случае — false
Логическое ИЛИ || x || y true, если x или y — true, в противном случае — false

Логическое НЕ

Мы уже с ним сталкивались в уроке 34 о типе данных boolean.

Логическое НЕ (оператор !)
Операнд Результат
true false
false true

Если операнд — true, то с применением логического НЕ он станет false. Если операнд до применения оператора — false, то с его применением станет — true. Другими словами, логический оператор НЕ меняет результат с true на false и наоборот.

Часто используется в условных выражениях:

Следует помнить, что логический оператор НЕ имеет очень высокий уровень приоритета. Новички часто совершают следующую ошибку:

Программа выведет «х equals у»! Но х ведь не равно у, как это возможно? Поскольку приоритет логического оператора НЕ выше, чем приоритет оператора равенства, выражение ! х == у будет вычисляться как (! х) == у. Так как х – это 5, то !x — это 0. Условие 0 == у ложное, поэтому выполняется часть else!

Напоминание: любое ненулевое целое значение в логическом контексте — true. Так как х = 5, то х вычисляется как true, а вот уже !x = false (0). Использование целых чисел в логических операциях подобным образом может запутать не только пользователя, но и самого разработчика, поэтому мы не советуем так делать!

Правильный способ написания фрагмента кода выше:

Сначала вычисляться будет х == у, затем оператор НЕ перевернет результат.

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

Правило: Используйте круглые скобки. Тогда не нужно будет помнить правила приоритета.

Логическое ИЛИ

Если хоть одно из двух условий истинно, то логический оператор ИЛИ – true. Если только левый операнд или только правый, или оба сразу true, результат — true.

Логическое ИЛИ (оператор ||)
Левый операнд Правый операнд Результат
false false false
false true true
true false true
true true true

Рассмотрим следующую программу:

Здесь мы использовали логический оператор ИЛИ чтобы проверить, является ли хоть одно из двух условий: левое (value == 0) или правое (value == 1) — true. Если это так или оба сразу истинны, то выполняться будет стейтмент if. Если ни одно не истинно, то результат – false и выполняться будет стейтмент else.

Вы можете соединить сразу несколько условий:

Новички иногда путают логическое ИЛИ (||) с побитовым ИЛИ (|). Хоть у них и одинаковые названия, функции они выполняют разные.

Логическое И

Только при условии, что оба операнда будут истинными, логический оператор И будет true. Если нет – false.

Логическое И (оператор &&)
Левый операнд Правый операнд Результат
false false false
false true false
true false false
true true true

Например, мы хотим знать, находится ли значение переменной х в диапазоне чисел от 10 до 20. Здесь на самом деле два условия: мы должны проверить, является ли х больше 10 и является ли х меньше 20.

Если два условия истинны, то выполняться будет часть if. Если хоть одно или оба сразу ложные, то выполняться будет часть else.

Как и с логическим ИЛИ, вы можете комбинировать вместе несколько условий И:

Короткий цикл вычислений

Для того, чтобы логическое И возвращало true, оба операнда должны быть истинными. Если первый операнд вычисляется как false, то оператор И должен сразу возвращать false независимо от результата второго операнда, даже без его обработки. Это называется короткий цикл вычислений (short circuit evaluation) и выполняется он, в первую очередь, в целях оптимизации.

Аналогично, если первый операнд логического ИЛИ — true, то и всё условие будет true, надобности вычислять второй операнд нет.

Как и в случае с оператором ИЛИ, новички иногда путают логическое И (&&) с побитовым И (&).

Использование И/ИЛИ

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

Многие программисты думают, что логические И и ИЛИ имеют одинаковый приоритет (или забывают, что это не так), так же как и сложение/вычитание или умножение/деление. Тем не менее, приоритет логического И выше приоритета ИЛИ, таким образом, операции с оператором И будут всегда вычисляться первыми (если только операции ИЛИ не находятся в круглых скобках).

Рассмотрим выражение:  value1 || value2 && value3. Поскольку приоритет логического И выше, то обрабатываться оно будет так: value1 || (value2 && value3), а не так: (value1 || value2) && value3.

Хорошей практикой является использование круглых скобок для заключения в них операций. Это предотвратит ошибки приоритета, увеличит читабельность кода и четко даст понять компилятору, как нужно обрабатывать выражения. Например, вместо того, чтобы писать value1 && value2 || value3 && value4, лучше записать (value1 && value2) || (value3 && value4).

Закон Де Моргана

Многие программисты совершают ошибку, думая, что !(x && y) — это то же самое, что и !x && !y. К сожалению, вы не можете «использовать» логическое НЕ таким образом.

Закон Де Моргана сообщает нам, как логическое НЕ должно использоваться в подобных случаях:

!(x && y) эквивалентно !x || !y
!(x || y) эквивалентно !x && !y

Другими словами, меняются операторы, с логического И на логическое ИЛИ и наоборот! В некоторых случаях, это даже полезно — улучшает читабельность.

Где же побитовое исключающее ИЛИ (XOR)?

Побитовое исключающее ИЛИ (XOR) — это логический оператор, который используется в некоторых языках для проверки на истинность нечетного количества условий.

Побитовое исключающее ИЛИ (XOR)
Левый операнд Правый операнд Результат
false false false
false true true
true false true
true true false

В C++ нет такого оператора. В отличии от логических И/ИЛИ, к XOR не применяется короткий цикл вычислений. Однако его легко можно сымитировать, используя оператор неравенства (!=):

Можно также расширить количество операндов:

Следует отметить, что приведенные выше шаблоны XOR работают только, если операнды булевы (не целые числа). Если хотите, чтобы это работало и с целыми числами — используйте static_cast.

Форма XOR, которая работает с не логическими операндами:

Тест

Вычислите следующие выражения:

 (true && true) || false

(false && true) || true

(false && true) || false || true

(5 > 6 || 4 > 3) && (7 > 8)

 !(7 > 6 || 3 > 4)

Ответы

Примечание: мы «объяснили выполнение», показывая шаги по которым добрались до окончательного ответа. Эти шаги разделены символом =>. Например, “(true || false) => true” означает, что результатом выражения “(true || false)” является выражение «true».

Ответ 1

(true && true) || false =>
true || false =>
true

Ответ 2

(false && true) || true =>
false || true =>
true

Ответ 3

(false && true) || false || true =>
false || false || true =>
false || true =>
true

Ответ 4

(5 > 6 || 4 > 3) && (7 > 8) =>
(false || true) && false =>
true && false =>
false

Ответ 5

!(7 > 6 || 3 > 4) =>
!(true || false) =>
!true =>
false

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (11 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *