$ sudo teach IT
Модуль 3 · Условный оператор

Урок 3.4 — Логические операторы

AND, OR, NOT — соединяем условия и строим сложную логику.

В реальной жизни условия редко бывают одиночными. «Если сегодня суббота И светит солнце, я иду гулять». «Если цена меньше 1000 ИЛИ товар в акции, я его куплю». «Если кнопка НЕ нажата, игра на паузе». В C# для соединения условий есть три логических оператора, которые мы сегодня разберём.

🔗

Оператор && (логическое И)

Оператор && (AND) возвращает true только тогда, когда оба условия истинны. Если хотя бы одно из них ложно — результат false.

Таблица истинности для && (И)
A
B
A && B
true
true
true
true
false
false
false
true
false
false
false
false

Запомни: && — строгий. Он говорит true только когда оба true. В остальных трёх случаях — false.

C# · Пример с &&
int age = 25;
bool hasLicense = true;

// Проверяем два условия сразу
if (age >= 18 && hasLicense)
{
    Console.WriteLine("Можно арендовать машину!");
}
else
{
    Console.WriteLine("Аренда недоступна.");
}

// Результат: "Можно арендовать машину!" — оба true
💡 В реальной жизни && работает как строгий охранник: «Пропущу, только если есть пропуск И документ».
🔀

Оператор || (логическое ИЛИ)

Оператор || (OR) возвращает true, если хотя бы одно из условий истинно. Он более «лояльный», чем &&.

Таблица истинности для || (ИЛИ)
A
B
A || B
true
true
true
true
false
true
false
true
true
false
false
false

Запомни: || — щедрый. Он даёт false только когда оба false. Во всех остальных случаях — true.

C# · Пример с ||
string role = "admin";
string password = "1234";

// Вход разрешён, если роль admin ИЛИ пароль правильный
if (role == "admin" || password == "secret")
{
    Console.WriteLine("Доступ разрешён!");
}
else
{
    Console.WriteLine("Доступ запрещён!");
}

// Результат: "Доступ разрешён!" — роль admin даёт true
💡 || в реальной жизни — как лояльный администратор: «Вход по пропуску ИЛИ по паспорту».
🚫

Оператор ! (логическое НЕ)

Оператор ! (NOT) — это унарный оператор (применяется к одному операнду). Он просто инвертирует значение: true превращает в false, false — в true.

Таблица истинности для ! (НЕ)
A
!A
true
false
false
true

В программировании ! используется постоянно: «если НЕ авторизован», «если НЕ пусто», «если НЕ равен».

C# · Пример с !
bool isOnline = false;

if (!isOnline)  // то же самое, что isOnline == false
{
    Console.WriteLine("Пользователь офлайн.");
}

// Или с методом, возвращающим bool:
string input = "";
if (!string.IsNullOrEmpty(input))
{
    Console.WriteLine($"Введено: {input}");
}
else
{
    Console.WriteLine("Строка пуста!");
}

💡 !isOnline читается как «НЕ isOnline». Если isOnline == false, то !isOnline == true. Это короче и красивее, чем писать isOnline == false. Профессиональные разработчики почти всегда используют ! вместо сравнения с false.

📊

Приоритет операторов: ! > && > ||

Логические операторы имеют разный приоритет (как в математике: умножение выполняется перед сложением). Приоритет убывает так:

Порядок выполнения (от высшего к низшему):

  1. ! — логическое НЕ (выполняется первым)
  2. && — логическое И (выполняется вторым)
  3. || — логическое ИЛИ (выполняется последним)

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

C# · Приоритет операторов
bool a = true;
bool b = false;
bool c = true;

bool result = !a || b && c;
// Шаг 1: !a → false
// Шаг 2: b && c → false && true → false
// Шаг 3: false || false → false
Console.WriteLine(result);  // False

Но лучшая практика — всегда ставить скобки, даже если помнишь приоритет. Код читают люди, а не только компилятор:

C# · Со скобками — понятнее
// Так читается сложнее:
if (!isWeekend || isHoliday && age >= 18) { }

// Со скобками — гораздо понятнее:
if (!isWeekend || (isHoliday && age >= 18)) { }
⚡

Short-circuit evaluation (короткое замыкание)

C# — умный язык. Он не вычисляет правую часть логического выражения, если результат уже ясен из левой части. Это называется short-circuit evaluation (сокращённое вычисление).

Правила короткого замыкания:

  • false && ... → результат false сразу, правая часть НЕ вычисляется. Зачем проверять второе условие, если первое уже false?
  • true || ... → результат true сразу, правая часть НЕ вычисляется. Если первое условие true, то ИЛИ уже истинно.

Это важно знать, потому что в правой части может быть вызов метода с побочным эффектом:

C# · Short-circuit в действии
// Пример 1: защита от ошибки (деление на ноль)
int divisor = 0;
if (divisor != 0 && 100 / divisor > 5)
{
    Console.WriteLine("Результат > 5");
}
// Без short-circuit: 100 / 0 → ошибка!
// Благодаря short-circuit: divisor != 0 → false, правая часть не выполняется

// Пример 2: проверка на null
string userName = null;
if (userName != null && userName.Length > 5)
{
    Console.WriteLine("Длинное имя");
}
// Без short-circuit: userName.Length → NullReferenceException!
// С short-circuit: userName != null → false → безопасно
💡 Это одна из причин, почему проверка на null (userName != null) всегда ставится первой. Если объект null — второе условие даже не запустится, и мы избегаем NullReferenceException.
🧩

Комбинирование нескольких условий

В реальных проектах условия бывают сложными. Давай соединим всё вместе. Представь систему бронирования билетов в кино:

C# · Система бронирования
int age = 16;
bool hasParent = true;
double money = 500;
double ticketPrice = 350;
bool isFilmForAdults = true;

// Проверка: можно ли купить билет?
bool canBuyTicket = (age >= 18 || hasParent)
                    && money >= ticketPrice
                    && (!isFilmForAdults || age >= 18 || hasParent);

if (canBuyTicket)
{
    Console.WriteLine("Билет куплен! Приятного просмотра.");
}
else
{
    Console.WriteLine("Не удалось купить билет.");
}

// Разберём условие:
// 1. (age >= 18 || hasParent) — возраст есть ИЛИ родитель с ним
// 2. money >= ticketPrice — денег хватает
// 3. (!isFilmForAdults || age >= 18 || hasParent) — фильм не 18+ ИЛИ возраст есть ИЛИ родитель
// Все три части должны быть true (соединены через &&)

⚠️ Сложные условия лучше разбивать на отдельные bool-переменные с понятными именами. Код станет читабельным и его легче отлаживать. Вместо длинного выражения можно написать несколько коротких и понятных строк.

Так же можно комбинировать && и || для проверки диапазонов:

C# · Проверка диапазона
int temperature = 25;

// Проверка: температура комфортная (от 18 до 30 включительно)
bool isComfortable = temperature >= 18 && temperature <= 30;
Console.WriteLine($"Температура комфортна: {isComfortable}");  // True

// Проверка: температура опасна (ниже 0 ИЛИ выше 45)
bool isDangerous = temperature < 0 || temperature > 45;
Console.WriteLine($"Температура опасна: {isDangerous}");  // False
🧪

Мини-тест

Проверь себя. Что выведет каждая из этих программ?

Вопрос 1

bool x = true;
bool y = false;
Console.WriteLine(x && y || x);

Варианты: A) True   B) False

Вопрос 2

int a = 5;
Console.WriteLine(!(a > 3) && a < 10);

Варианты: A) True   B) False

Вопрос 3

int value = 0;
bool res = value != 0 && 100 / value > 1;
Console.WriteLine(res);

Варианты: A) True   B) False   C) Ошибка выполнения

Вопрос 4

string name = null;
if (name != null && name.Length > 0)
    Console.WriteLine("OK");
else
    Console.WriteLine("NOT OK");

Что будет? A) OK   B) NOT OK   C) NullReferenceException

💡 Ответы: 1 — A (&& выполняется первым: true && false = false, false || true = true). 2 — B (!(5>3) → false, false && true = false). 3 — B (value != 0 → false, short-circuit → правая часть не вычисляется, ошибки нет). 4 — B (name != null → false, short-circuit → else).
🎮

Задача

Задание: Калькулятор доставки

Интернет-магазин доставляет заказы. Напиши программу, которая определяет, полагается ли клиенту бесплатная доставка.

Условия бесплатной доставки:

  • Сумма заказа больше или равна 2000 рублей
  • ИЛИ клиент является премиум-участником (isPremium == true)
  • ИЛИ сегодня день рождения клиента (isBirthday == true)

Дополнительно: вес заказа не должен превышать 50 кг.

Ввод:

  • Сумма заказа (double)
  • Вес заказа (double)
  • Премиум-участник (bool, ввести true/false)
  • День рождения сегодня (bool)

Выведи: «Доставка бесплатна» или «Стоимость доставки: X рублей» (где X = вес * 10, если бесплатная доставка не положена).

💡 Подсказка: используй комбинацию && и ||. Сначала проверь бесплатную доставку, потом — превышение веса. Вес — обязательное условие: даже если доставка бесплатна по сумме, при весе > 50 кг доставка платная.
📌

Что важно запомнить

1️⃣
&& (И) — true только когда оба true. || (ИЛИ) — false только когда оба false. ! (НЕ) — инвертирует значение.
2️⃣
Приоритет: ! (высший) → && → || (низший). Используй скобки для ясности.
3️⃣
Short-circuit: false && ... сразу false, true || ... сразу true. Правая часть не вычисляется.
4️⃣
Проверка на null всегда должна быть первой в цепочке &&: if (user != null && user.Name != "")
5️⃣
Читаемость: сложные условия разбивай на отдельные bool-переменные с осмысленными именами.

Тест: 3.4: Логические операторы

5 вопросов

Тернарный оператор

Premium