Таблица истинности и логические операции: как читать и применять в коде
Знакомая ситуация. Вы пишете в коде проверку: «показать кнопку отправки, если пользователь авторизован и не находится в режиме гостя или если у него есть админские права». В голове логика ясна. На клавиатуре получается что-то вроде:
if (user.isAuthenticated && !user.isGuest || user.isAdmin) {
showSubmitButton();
}Через две недели тестировщик находит баг: гостям с правами админа кнопку не показывают. Вы садитесь разбираться и не сразу понимаете, в чём дело. Проблема в порядке операций: && выполняется раньше ||, поэтому реальная логика выглядит как (isAuthenticated && !isGuest) || isAdmin — это правильно. Но если такого порядка не знать, в условии легко запутаться.
Тут и помогает таблица истинности. Вы перебираете все восемь возможных комбинаций трёх флагов, видите результат — и сразу замечаете, где условие даёт не то, что ожидалось. Это базовый инструмент, которым стоит уметь пользоваться любому, кто пишет код с ветвлениями.
Дальше — что такое логика высказываний, как читать и строить таблицы истинности, какие шесть основных операций есть и где они встречаются в реальном программировании. И встроенный калькулятор, который строит таблицу по вашей формуле.
Логика высказываний за две минуты
В логике высказываний любое утверждение — либо истина, либо ложь. Промежуточных вариантов нет. «Сегодня вторник» — истина или ложь, без оттенков. «x больше 5» — истина или ложь, в зависимости от того, чему равно x.
В коде эти два значения называются true и false или 1 и 0. Все условные конструкции — if, while, тернарный оператор — работают именно с такими значениями. Операторы сравнения (==, !=, <, >) превращают любое выражение в булево значение, дальше его можно комбинировать с другими булевыми значениями через логические операции.
Из простых высказываний с помощью логических операций строятся сложные. «Пользователь авторизован» — простое высказывание, либо истина, либо ложь. «Пользователь авторизован и его подписка активна» — сложное высказывание, которое истинно только если оба простых истинны.
Что такое таблица истинности
Таблица истинности — это перечисление всех возможных комбинаций значений переменных в выражении и результата для каждой комбинации. Если переменных одна, в таблице две строки. Если две — четыре строки. Если три — восемь строк. Общая формула: 2 в степени n, где n — количество переменных.
Пример таблицы истинности для двух переменных и операции «И»:
A | B | A И B |
|---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Из таблицы сразу видно правило операции «И»: результат истинен только когда оба аргумента истинны. Если хотя бы один — ложь, результат тоже ложь.
Главная польза таблиц истинности на практике — когда у вас сложное условие с тремя-четырьмя флагами, и нужно понять, во всех ли случаях оно ведёт себя так, как задумано. Построили таблицу — увидели результат для каждой комбинации — нашли строку, где результат не такой, как ожидался. Это быстрее, чем дебажить руками.
Шесть основных логических операций

В большинстве языков программирования есть четыре базовые операции: И, ИЛИ, НЕ, XOR. Плюс две из теории: импликация и эквивалентность — они в чистом виде встречаются редко, но иногда полезны для рассуждений о коде.
И (конъюнкция, AND)
Обозначения: && в большинстве языков, and в Python, символ ∧ в математике.
Правило: истина только когда оба аргумента истинны.
A | B | A && B |
|---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Где встречается: «пользователь авторизован и у него есть права», «значение больше нуля и меньше ста», «файл существует и доступен на чтение». Везде, где требуется выполнение нескольких условий одновременно.
ИЛИ (дизъюнкция, OR)
Обозначения: ||, or в Python, символ ∨.
Правило: истина если хотя бы один аргумент истинен. Ложь только когда оба ложны.
A | B | A || B |
|---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Где встречается: «выходной — суббота или воскресенье», «пользователь админ или модератор», «значение равно null или пустая строка». Альтернативы, любая из которых даёт результат.
НЕ (инверсия, NOT)
Обозначения: !, not в Python, символ ¬.
Правило: переворачивает значение. Истина становится ложью, ложь — истиной.
A | !A |
|---|---|
0 | 1 |
1 | 0 |
Где встречается: «пользователь не авторизован», «значение не равно null», «массив не пустой». Отрицание условия, противоположный случай.
XOR (исключающее ИЛИ)
Обозначения: ^ в C-подобных языках для битов, xor в некоторых языках, символ ⊕.
Правило: истина только когда аргументы различаются. Если оба одинаковые (оба 0 или оба 1) — ложь.
A | B | A ⊕ B |
|---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Где встречается реже — в основном в криптографии, обработке битовых масок, проверках «ровно одно из двух». На уровне условий if XOR обычно записывается через комбинацию != для булевых значений: isAdmin != isGuest даёт тот же результат, что isAdmin XOR isGuest.
Импликация (следование, →)
В большинстве языков программирования отдельного оператора нет. Записывается как !A || B.
Правило: «если A, то B». Ложь только в одном случае — когда A истина, а B ложь. Во всех остальных — истина.
A | B | A → B |
|---|---|---|
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 1 | 1 |
Где встречается на практике: формулировки требований и инвариантов. «Если пользователь админ, то у него есть доступ к панели управления» — это импликация. В тестах: «если функция вызвана с null, то выбрасывается исключение».
Эквивалентность (↔)
В коде записывается как A == B для булевых.
Правило: истина когда A и B одинаковы (оба истина или оба ложь). Иначе ложь.
A | B | A ↔ B |
|---|---|---|
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Где встречается: проверка совпадения двух булевых значений. «Кнопка активна тогда и только тогда, когда форма валидна».
Приоритет операций: в каком порядке выполняются

В сложном выражении вроде !A && B || C важно знать, какая операция выполняется первой. Иначе получится результат, отличный от ожидаемого.
Порядок выполнения (от высшего приоритета к низшему):
НЕ (
!) — выполняется первойИ (
&&)ИЛИ (
||)
Это означает, что выражение !A && B || C читается как ((!A) && B) || C. Сначала инверсия A, потом конъюнкция с B, потом дизъюнкция с C.
Главное правило хорошего кода: не полагайтесь на приоритет в сложных выражениях. Если есть малейшее сомнение — расставьте скобки. Это не делает код медленнее (компилятор всё равно расставит их сам), но делает читаемым.
Сложно понять:
if (isAuth && !isGuest || isAdmin) {
...
}Понятно с первого взгляда:
if ((isAuth && !isGuest) || isAdmin) {
...
}Закон де Моргана: главная польза в коде

Из всех законов алгебры логики самый практически полезный — закон де Моргана. Он показывает, как раскрыть отрицание сложного выражения. Формулировка:
!(A && B)равно!A || !B!(A || B)равно!A && !B
Простой пример. Допустим, у вас есть условие «пользователь авторизован И его подписка активна». Вам нужно сделать обратное — «случай, когда это условие не выполняется». Дословный перевод:
if (!(isAuth && isActive)) {
showLoginPrompt();
}По закону де Моргана это эквивалентно более читаемому коду:
if (!isAuth || !isActive) {
showLoginPrompt();
}Второй вариант читается лучше: «если не авторизован или подписка не активна». Это конкретные случаи, а не «отрицание всего». С пониманием этого правила сложные отрицания превращаются в естественные формулировки.
Обратный случай. У вас условие «не админ И не модератор». Это можно переписать как «не (админ или модератор)»:
if (!isAdmin && !isModerator) // →
if (!(isAdmin || isModerator))Какой вариант лучше — зависит от контекста. Иногда нагляднее перечислить случаи через «и», иногда — выделить общее свойство «ни один из».
Короткая оценка: то, что не написано в таблицах истинности
На уровне теории логики операции И и ИЛИ симметричны: A && B и B && A дают одинаковый результат. На уровне кода у этой симметрии есть важное исключение — короткая оценка (short-circuit evaluation).
В большинстве языков программирования && и || вычисляются слева направо и останавливаются, как только результат становится известен:
false && что-угодно— что-угодно даже не вычисляется. Результат уже известенtrue || что-угодно— то же самое
Это меняет правила игры на практике. Например:
if (user != null && user.isActive) {
// безопасно: если user == null, user.isActive не выполнится
}Этот код безопасен от NullPointerException. Если бы операторы были симметричными и второй аргумент всегда вычислялся, такой код падал бы на каждом запросе с пустым user. Короткая оценка спасает.
А вот этот код будет падать:
if (user.isActive && user != null) { // ← порядок неправильный
...
}Здесь сначала вычислится user.isActive на null-объекте, и программа упадёт ещё до проверки на null. Порядок аргументов в логических операторах имеет значение.
Калькулятор таблиц истинности
Введите формулу с переменными A, B, C и операторами:
!— НЕ (например,!A)&&— И||— ИЛИ^— XOR(и)— скобки
Импликация A → B записывается как !A || B. Эквивалентность A ↔ B — как !(A ^ B).
Попробуйте: (A && B) || !C, A ^ B, !(A && B), !A || !B — последние две формулы должны дать одинаковые таблицы по закону де Моргана.
Формула:Построить таблицу
A | B | C | Результат |
|---|---|---|---|
0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
1 | 1 | 1 | 1 |
Как построить таблицу истинности вручную
Иногда калькулятора под рукой нет, или хочется разобраться в логике пошагово. Алгоритм построения таблицы вручную:
Шаг | Что делать |
|---|---|
1 | Выпишите все переменные в выражении. Например, для |
2 | Посчитайте число строк: 2 в степени n. Для трёх переменных — 8 строк |
3 | Заполните столбцы переменных всеми комбинациями. Удобный порядок: в первом столбце половина нулей и половина единиц, во втором — четверти, в третьем — попеременно 0 и 1 |
4 | Если выражение сложное, добавьте промежуточные столбцы. Например, для |
5 | В каждой строке примените правила операций согласно приоритету. Запишите результат в последний столбец |
Пример заполнения для (A && B) || !C:
A | B | C | A && B | !C | Результат |
|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 1 | 1 |
0 | 1 | 1 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 1 | 1 |
1 | 0 | 1 | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 1 |
Где это применяется в реальном коде
Несколько типичных мест, где знание логики высказываний даёт практическую пользу.
Сложные условия в if
Когда в условии больше двух переменных, легко запутаться. Таблица истинности — способ проверить все случаи и убедиться, что код ведёт себя ожидаемо. Особенно полезно для бизнес-логики вроде «если пользователь premium и подписка не просрочена, или у него триал, и он не превысил лимит — открыть доступ».
Упрощение условий через закон де Моргана
Когда видите конструкцию вида !(A && B) или !(A || B) — это сигнал подумать, не записать ли её через распределённое отрицание. Часто получается короче и понятнее.
Тестирование граничных случаев
Таблица истинности — это готовый список тест-кейсов для функции с булевыми параметрами. Если у функции три флага, нужно протестировать восемь случаев. Таблица показывает все восемь.
Битовые маски и флаги
В системном программировании часто используются битовые операции — те же логические, но для всех битов числа одновременно. Понимание таблиц истинности здесь критично. Например, проверка «бит 3 установлен и бит 5 не установлен» — это типичная задача для битмаски.
SQL-запросы и фильтры
В SQL точно те же логические операторы: AND, OR, NOT. Сложный WHERE-клауз с несколькими условиями подчиняется тем же правилам приоритета.
Регулярные выражения и поиск
Логика «или» (a|b), «не» (отрицательные классы), группировки в регэкспах — это применение логических операций к шаблонам.
Антипаттерны при работе с логикой
Двойное отрицание для усиления. if (!!isReady) — это просто if (isReady). Никакого усиления нет, только лишний шум. Двойное отрицание иногда используется для приведения значения к булеву типу, но в большинстве современных языков это не нужно.
Полагаться на приоритет вместо скобок. !a && b || c && !d — приоритет правильный, но прочитать с первого раза тяжело. Скобки (!a && b) || (c && !d) делают то же самое, но понятно.
Сравнение с булевыми константами. if (isActive == true) вместо if (isActive). Лишний шум, и легко опечататься в = вместо ==. То же про if (isActive == false) — пишите if (!isActive).
Длинные цепочки И/ИЛИ без структурирования. if (a && b && c && d && e && f) — если условий больше трёх, выносите в отдельную функцию с осмысленным именем. if (isReadyForCheckout(user, cart, payment)) читается лучше.
Неправильный порядок при null-проверках. if (user.isActive && user != null) — упадёт на null-юзере, потому что проверка user.isActive вычислится первой. Правильно: if (user != null && user.isActive).
FAQ
Сколько строк должно быть в таблице истинности?
2 в степени n, где n — число различных переменных. Одна переменная — 2 строки, две — 4, три — 8, четыре — 16. Для пяти переменных уже 32 строки — обычно в этот момент проще декомпозировать условие.
Чем калькулятор отличается от таблицы?
Калькулятор обычно подставляет конкретные значения и считает один результат. Таблица перебирает все возможные комбинации — это полная картина поведения формулы.
Зачем программисту знать про импликацию?
На уровне кода она встречается редко. На уровне рассуждений о коде — постоянно. Любое утверждение вида «если X, то Y» — это импликация. Контракты функций, инварианты данных, требования к API — всё это логические импликации.
Почему в калькуляторе нет специального символа для XOR?
В калькуляторе используется ^ — стандартное обозначение XOR в C, Java, JavaScript, Python для битовых операций. Для булевых значений в большинстве языков отдельного оператора XOR нет — он выражается через комбинацию других, например A != B.
Что важнее в коде — короткие условия или явные?
Явные. Короткое условие, в котором приходится разбираться, хуже длинного, которое читается с первого раза. Если в коде сложная булева логика, лучше потратить две строки на её ясное выражение, чем уместить в одну.
Как тестировать функции со сложными булевыми условиями?
Постройте таблицу истинности — она даёт вам полный список тест-кейсов. Если у функции 3 булевых параметра, нужно 8 тестов. В тестах используйте параметризацию: pytest.parametrize в Python, theory в xUnit, describe.each в Jest. Так удобнее — не приходится дублировать код тестов для каждой комбинации.
Стоит ли использовать XOR в условиях if?
Редко. На булевых значениях XOR обычно записывается как !=, и это понятнее. Где XOR действительно нужен — это битовые операции, шифрование, генерация хэшей. В типичной бизнес-логике приложения XOR встречается раз в год.






