Урок 3.4 — Логические операторы
AND, OR, NOT — соединяем условия и строим сложную логику.
В реальной жизни условия редко бывают одиночными. «Если сегодня суббота И светит солнце, я иду гулять». «Если цена меньше 1000 ИЛИ товар в акции, я его куплю». «Если кнопка НЕ нажата, игра на паузе». В C# для соединения условий есть три логических оператора, которые мы сегодня разберём.
Оператор && (логическое И)
Оператор && (AND) возвращает true только тогда, когда оба условия истинны. Если хотя бы одно из них ложно — результат false.
Запомни: && — строгий. Он говорит true только когда оба true. В остальных трёх случаях — false.
int age = 25;
bool hasLicense = true;
// Проверяем два условия сразу
if (age >= 18 && hasLicense)
{
Console.WriteLine("Можно арендовать машину!");
}
else
{
Console.WriteLine("Аренда недоступна.");
}
// Результат: "Можно арендовать машину!" — оба true
Оператор || (логическое ИЛИ)
Оператор || (OR) возвращает true, если хотя бы одно из условий истинно. Он более «лояльный», чем &&.
Запомни: || — щедрый. Он даёт false только когда оба false. Во всех остальных случаях — true.
string role = "admin";
string password = "1234";
// Вход разрешён, если роль admin ИЛИ пароль правильный
if (role == "admin" || password == "secret")
{
Console.WriteLine("Доступ разрешён!");
}
else
{
Console.WriteLine("Доступ запрещён!");
}
// Результат: "Доступ разрешён!" — роль admin даёт true
Оператор ! (логическое НЕ)
Оператор ! (NOT) — это унарный оператор (применяется к одному операнду). Он просто инвертирует значение: true превращает в false, false — в true.
В программировании ! используется постоянно: «если НЕ авторизован», «если НЕ пусто», «если НЕ равен».
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.
Приоритет операторов: ! > && > ||
Логические операторы имеют разный приоритет (как в математике: умножение выполняется перед сложением). Приоритет убывает так:
Порядок выполнения (от высшего к низшему):
- ! — логическое НЕ (выполняется первым)
- && — логическое И (выполняется вторым)
- || — логическое ИЛИ (выполняется последним)
Посмотри на пример и догадайся, как он выполняется:
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
Но лучшая практика — всегда ставить скобки, даже если помнишь приоритет. Код читают люди, а не только компилятор:
// Так читается сложнее:
if (!isWeekend || isHoliday && age >= 18) { }
// Со скобками — гораздо понятнее:
if (!isWeekend || (isHoliday && age >= 18)) { }
Short-circuit evaluation (короткое замыкание)
C# — умный язык. Он не вычисляет правую часть логического выражения, если результат уже ясен из левой части. Это называется short-circuit evaluation (сокращённое вычисление).
Правила короткого замыкания:
false && ...→ результат false сразу, правая часть НЕ вычисляется. Зачем проверять второе условие, если первое уже false?true || ...→ результат true сразу, правая часть НЕ вычисляется. Если первое условие true, то ИЛИ уже истинно.
Это важно знать, потому что в правой части может быть вызов метода с побочным эффектом:
// Пример 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 → безопасно
userName != null) всегда ставится первой. Если объект null — второе условие даже не запустится, и мы избегаем NullReferenceException.Комбинирование нескольких условий
В реальных проектах условия бывают сложными. Давай соединим всё вместе. Представь систему бронирования билетов в кино:
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-переменные с понятными именами. Код станет читабельным и его легче отлаживать. Вместо длинного выражения можно написать несколько коротких и понятных строк.
Так же можно комбинировать && и || для проверки диапазонов:
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
Задача
Задание: Калькулятор доставки
Интернет-магазин доставляет заказы. Напиши программу, которая определяет, полагается ли клиенту бесплатная доставка.
Условия бесплатной доставки:
- Сумма заказа больше или равна 2000 рублей
- ИЛИ клиент является премиум-участником (isPremium == true)
- ИЛИ сегодня день рождения клиента (isBirthday == true)
Дополнительно: вес заказа не должен превышать 50 кг.
Ввод:
- Сумма заказа (double)
- Вес заказа (double)
- Премиум-участник (bool, ввести true/false)
- День рождения сегодня (bool)
Выведи: «Доставка бесплатна» или «Стоимость доставки: X рублей» (где X = вес * 10, если бесплатная доставка не положена).
Что важно запомнить
! (высший) → && → || (низший). Используй скобки для ясности.false && ... сразу false, true || ... сразу true. Правая часть не вычисляется.if (user != null && user.Name != "")Тест: 3.4: Логические операторы
5 вопросов