Логические операции в C++
Так как в предыдущей статье, я впервые использовал логическую операцию, расскажу, какие они бывают, сколько их и как ими пользоваться.
В С++ существует три логические операции:
- Логическая операция И && , нам уже известная;
- Логическая операция ИЛИ || ;
- Логическая операция НЕ ! или логическое отрицание.
Логические операции образуют сложное (составное) условие из нескольких простых (два или более) условий. Эти операции упрощают структуру программного кода в несколько раз. Да, можно обойтись и без них, но тогда количество ифов увеличивается в несколько раз, в зависимости от условия. В следующей таблице кратко охарактеризованы все логические операции в языке программирования С++, для построения логических условий.
| Операции | Обозначение | Условие | Краткое описание |
|---|---|---|---|
| И | && | a == 3 && b > 4 | Составное условие истинно, если истинны оба простых условия |
| ИЛИ | || | a == 3 || b > 4 | Составное условие истинно, если истинно, хотя бы одно из простых условий |
| НЕ | ! | !( a == 3) | Условие истинно, если a не равно 3 |
Сейчас следует понять разницу между логической операцией И и логической операцией ИЛИ , чтобы в дальнейшем не путаться. Пришло время познакомиться с типом данных bool –логический тип данных. Данный тип данных может принимать два значения: true (истина) и false (ложь). Проверяемое условие в операторах выбора имеет тип данных bool . Рассмотрим принцип работы следующей программы, и все будет понятно со всеми этими логическими операциями.
Строки 9 и 10 вам должны быть понятны, так как здесь инициализируются переменные типа bool . Причем каждой переменной присваивается значение true или false . Начиная с 9-й строки и заканчивая 20-й , показано использование логических операций. Результат работы программы (см. Рисунок 1).
Рисунок 1 — Логические операции С++
Наверное, у вас возникает вопрос, «А что это за нолики и единички?». Если есть вопрос, то на него нужно ответить. Отвечаю: «Нолик-это представление логического значения false (ложь), ну а единички – это логическое true (истина)». Коротко поясню некоторые моменты. Составное условие с использованием логического И истинно только в том случае, когда истинны оба простых условия. Во всех остальных случаях составное условие ложно. Составное условие с использованием логического ИЛИ ложно только в том случае, когда ложные оба простых условия. Во всех остальных случаях составное условие истинно. Логическое отрицание НЕ является унарной операцией, и она не комбинирует два условия, в отличие от логических операций И и ИЛИ , которые являются бинарными операциями. Логическое отрицание позволяет перевернуть смысл условия, что в некоторых случаях очень удобно. Условие с логическим отрицанием истинно в том случае, если это же условие ложно без отрицания, и наоборот.
Логические операторы в си
Л огические операторы – это операторы, которые принимают в качестве аргументов логические значений (ложь или истину) и возвращают логическое значение. Как и обычные операторы, они могут быть одноместными (унарными, т.е. принимать один аргумент), двуместными (бинарные, принимают два аргумента), трёхместными и т.д.
Особенностью языка си является то, что в нём нет типа, хранящего булево значение (ложь или истину). В си ложью (логическим нулём) считается целочисленный 0, а любое ненулевое целое будет логической истиной. Например
Логические значения обычно порождаются операторами сравнения (==, !=, >, <, >=. <=).
В языке си представлено три логических оператора: И, ИЛИ и НЕ. Начнём с самого простого
Логическое отрицание
О ператор НЕ (NOT) используется для того, чтобы инвертировать значение аргумента. Т.е., если ему передали истину, то он вернёт ложь, если получил ложь в качестве аргумента, то вернёт истину.
| X | NOT X |
|---|---|
| 0 | 1 |
| 1 | 0 |
В си отрицание представлено оператором !. Например
Как и в обычной логике, здесь действует закон двойного отрицания – отрицание отрицания можно опустить.
Логическое И
О ператор И (AND, логическое умножение) возвращает истину тогда и только тогда, когда оба аргумента являются истиной.
| X | Y | X AND Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
В си логическое умножение представлено оператором &&. Например, задача – в кружок военных спейсмаринов допускаются только совершеннолетние граждане мужского пола. То есть, претендентом может стать только тот, для которого одновременно два условия являются истиной
Оператор И может применяться последовательно к нескольким аргументам. Для него действует ассоциативный и коммутативный законы. Усовершенствуем программу, будем также вводить рост:
Также условие могло быть записано
Логическое ИЛИ
О ператор логическое ИЛИ (логическое сложение, OR) истинен тогда, когда истиной является хотя бы один его аргумент.
| X | Y | X OR Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
В си ИЛИ представлен оператором ||. Например, усовершенствуем программу: теперь пол можно вводить как большой, так и маленькой буквой
Как и в случае оператора И, ИЛИ коммутативен и ассоциативен.
Операторы можно перемешивать друг с другом, создавая сложные операторы
Стоит только помнить о том, что оператор отрицания имеет больший приоритет, чем И или ИЛИ, поэтому будет выполняться в первую очередь. Если может случиться ситуация, когда порядок выполнения не ясен, определите его с помощью скобок.
Пример: закон де-Моргана. Чтобы сменить И на ИЛИ (или наоборот), необходимо инвертировать значения всех операндов, заменить И на ИЛИ (или ИЛИ на И) и инвертировать конечный результат. В случае с нашим условием
Рассмотрим сначала кусок
Меняем все значения на обратные
заменяем оператор && на ||
и инвертируем ответ
Как видим, результат тот же. Очевидно, что
Таким образом, изменим условие
Поменяем таким же образом вторую скобку
Теперь можно применить это же правило и для всего выражения
Порядок выполнения логических операторов
Р ассмотрим выражение
где a, b, c, d – логические значения. Всё выражение равно истине тогда и только тогда, когда все операнды истинны. Если хотя бы один из операндов ложь, то остальные уже не важны. Поэтому, для оптимизации работы, вычисление происходит слева направо и останавливается, как только был найден первый операнд, равный нулю.
В си оператор присваивания может возвращать значение. Иногда он используется непосредственно в условии:
В данном случае, оператор malloc не будет выполнен, так как первый операнд a равен 0 (соответственно, всё выражение равно нулю). Таким образом, оператор free попытается очистить память, которую не может очистить (т.к. p продолжит ссылаться на a). Если же мы поменяем a = 1, то всё отработает без проблем.
То же самое происходит и при выполнение ||. Выражение
выполняется слева направо до тех пор, пока не встретит первое ненулевое значение. После этого выполнение останавливается, так как известно, что всё выражение равно истине.
Очевидно, что это касается не только оператора присваивания, но и любого другого вызова функции. Например, в этом случае функции foo будет вызвана, bar нет.
Вывод – не используйте присваивания и вызовов функций (особенно, если они изменяют состояние программы) внутри условий.

Всё ещё не понятно? – пиши вопросы на ящик
Урок №43. Логические операторы: И, ИЛИ, НЕ
На этом уроке мы рассмотрим логические операторы И, ИЛИ и НЕ в языке С++.
Логические операторы
В то время как операторы сравнения используются для проверки конкретного условия: ложное оно или истинное, они могут проверить только одно условие за определенный промежуток времени. Но бывают ситуации, когда нужно протестировать сразу несколько условий. Например, чтобы узнать, выиграли ли мы в лотерею, нам нужно сравнить все цифры купленного билета с выигрышными. Если в лотерее 6 цифр, то нужно выполнить 6 сравнений, все из которых должны быть true.
Также иногда нам нужно знать, является ли хоть одно из нескольких условий истинным. Например, мы не пойдем сегодня на работу, если больны или слишком устали, или если выиграли в лотерею. Нам нужно проверить, является ли хоть одно из этих трех условий истинным. Как это сделать? С помощью логических операторов! Они позволяют проверить сразу несколько условий за раз.
В языке C++ есть 3 логических оператора:
| Оператор | Символ | Пример | Операция |
| Логическое НЕ | ! | !x | true, если x — false и false, если x — true |
| Логическое И | && | x && y | true, если x и y — true, в противном случае — false |
| Логическое ИЛИ | || | x || y | true, если x или y — true, в противном случае — false |
Логический оператор НЕ
Мы уже с ним сталкивались на уроке №34.
| Логический оператор НЕ (!) | |
| Операнд | Результат |
| true | false |
| false | true |
Если операндом является true, то, после применения логического НЕ, результатом будет false. Если же операнд до применения оператора НЕ был false, то после его применения станет true. Другими словами, логический оператор НЕ меняет результат на противоположный начальному значению. Он часто используется в условных выражениях:
Следует помнить, что логический оператор НЕ имеет очень высокий уровень приоритета. Новички часто совершают следующую ошибку:
Результат выполнения программы:
Но х ведь не равно у , как это возможно? Поскольку приоритет логического оператора НЕ выше, чем приоритет оператора равенства, то выражение ! х == у обрабатывается как (! х) == у . Так как х — это 5 , то !x — это 0 . Условие 0 == у ложное, поэтому выполняется часть else!
Напоминание: Любое ненулевое целое значение в логическом контексте является true. Так как х = 5 , то х вычисляется как true, а вот !x = false , т.е. 0 . Использование целых чисел в логических операциях подобным образом может запутать не только пользователя, но и самого разработчика, поэтому так не рекомендуется делать!
Правильный способ написания программы, приведенной выше:
Сначала обрабатывается х == у , а затем уже оператор НЕ изменяет результат на противоположный.
Правило: Если логический оператор НЕ должен работать с результатами работы других операторов, то другие операторы и их операнды должны находиться в круглых скобках.
Логический оператор ИЛИ
Если хоть одно из двух условий является истинным, то логический оператор ИЛИ является true.
| Логический оператор ИЛИ (||) | ||
| Левый операнд | Правый операнд | Результат |
| false | false | false |
| false | true | true |
| true | false | true |
| true | true | true |
Рассмотрим следующую программу:
Здесь мы использовали логический оператор ИЛИ, чтобы проверить, является ли хоть одно из двух условий истинным: левое ( value == 0 ) или правое ( value == 1 ). Если хоть одно из условий — true или оба сразу true, то выполняться будет стейтмент if. Если ни одно из условий не является true, то результат — 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 не применяется короткий цикл вычислений. Однако его легко можно сымитировать, используя оператор неравенства ( != ):
Logical operators
Logical operators apply standard boolean algebra operations to their operands.
| Operator | Operator name | Example | Result |
|---|---|---|---|
| ! | logical NOT | ! a | the logical negation of a |
| && | logical AND | a && b | the logical AND of a and b |
| || | logical OR | a || b | the logical OR of a and b |
| ! expression |
| expression | — | an expression of any scalar type |
The logical NOT operator has type int . Its value is 0 if expression evaluates to a value that compares unequal to zero. Its value is 1 if expression evaluates to a value that compares equal to zero. (so ! E is the same as ( 0 == E ) )
[edit] Logical AND
The logical AND expression has the form
| lhs && rhs |
| lhs | — | an expression of any scalar type |
| rhs | — | an expression of any scalar type, which is only evaluated if lhs does not compare equal to 0 |
The logical-AND operator has type int and the value 1 if both lhs and rhs compare unequal to zero. It has the value 0 otherwise (if either lhs or rhs or both compare equal to zero).
There is a sequence point after the evaluation of lhs . If the result of lhs compares equal to zero, then rhs is not evaluated at all (so-called short-circuit evaluation)
[edit] Logical OR
The logical OR expression has the form
| lhs || rhs |
| lhs | — | an expression of any scalar type |
| rhs | — | an expression of any scalar type, which is only evaluated if lhs compares equal to 0 |
The logical-OR operator has type int and the value 1 if either lhs or rhs compare unequal to zero. It has value 0 otherwise (if both lhs and rhs compare equal to zero).
There is a sequence point after the evaluation of lhs . If the result of lhs compares unequal to zero, then rhs is not evaluated at all (so-called short-circuit evaluation)
[edit] References
- C11 standard (ISO/IEC 9899:2011):
- 6.5.3.3 Unary arithmetic operators (p: 89)
- 6.5.13 Logical AND operator (p: 99)
- 6.5.14 Logical OR operator (p: 99)
- C99 standard (ISO/IEC 9899:1999):
- 6.5.3.3 Unary arithmetic operators (p: 79)
- 6.5.13 Logical AND operator (p: 89)
- 6.5.14 Logical OR operator (p: 89)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.3.3.3 Unary arithmetic operators
- 3.3.13 Logical AND operator
- 3.3.14 Logical OR operator
[edit] See Also
a = b
a + = b
a — = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b