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

Урок 3.2 — Оператор if-else

Программа начинает думать — выбирает, что делать в зависимости от условия.

В реальной жизни мы постоянно принимаем решения: «Если на улице дождь — возьми зонт, иначе (else) — надень панаму». В программировании работает та же логика. if — это способ сказать компьютеру: «Проверь условие и выполни разные действия в зависимости от результата». Это основа почти любой программы.

🔀

Синтаксис if

Базовый синтаксис условного оператора в C#:

if (условие) { тело }

Если условие истинно (true) — выполнится код внутри фигурных скобок. Если ложно (false) — пропустится.

C# · Простейший if
int age = 20;

if (age >= 18)
{
    Console.WriteLine("Вы совершеннолетний");
}

// Условие — это любое выражение, которое даёт bool:
bool isAdult = age >= 18;
if (isAdult)
{
    Console.WriteLine("Всё верно: isAdult = true");
}

// Можно использовать любые сравнения:
if (age == 18)
{
    Console.WriteLine("Ровно 18 — ни больше, ни меньше");
}

if (age != 18)
{
    Console.WriteLine("Не 18");
}
💡 Условие в if всегда должно быть bool. Нельзя написать if (5) как в Python или C++. Только if (5 > 3) или if (someBoolVariable).
↔️

if-else: выбор из двух вариантов

Блок else выполняется, когда условие в if ложно. Синтаксис:

if (условие) { тело_если_true } else { тело_если_false }

C# · if-else
int temperature = 25;

if (temperature > 20)
{
    Console.WriteLine("Тепло — можно гулять в футболке");
}
else
{
    Console.WriteLine("Прохладно — надень куртку");
}

// Важно: выполнится только одна ветка (или if, или else)
// Никогда обе сразу.

💡 Главное правило: if и else — две альтернативы. Выполнится ровно одна из них. Никогда обе. Никогда ни одна (если только нет else, тогда при false не выполнится ничто, но это тоже нормально).

{ }

Фигурные скобки: всегда ставь их

В C# если после if или else идёт только одна инструкция, фигурные скобки можно опустить. Но мы категорически не рекомендуем это делать.

❌ Без скобок — опасный стиль

if (age >= 18)
    Console.WriteLine("Взрослый");  // только эта строка под if
    Console.WriteLine("Проверка пройдена"); // А ЭТА ВСЕГДА выполняется!
    // Она не входит в if! Отступы обманывают глаз.

Хотя отступы подсказывают, что обе строки в if, на самом деле только первая. Вторая выполняется всегда. Это классическая ошибка.

✅ Со скобками — безопасно

if (age >= 18)
{
    Console.WriteLine("Взрослый");
    Console.WriteLine("Проверка пройдена");  // обе под if
}

Скобки явно показывают границы блока. Нельзя ошибиться.

⚠️ Железное правило: всегда ставь фигурные скобки после if, else, for, while, foreach. Даже для одной строки. Это стиль Microsoft, стиль всех профессиональных C#-разработчиков, и это спасёт тебя от сотен часов отладки.

📏

Одна строка: можно ли без скобок?

Технически — да, можно. C# позволяет опустить фигурные скобки, если в блоке одна инструкция:

C# · Одна строка (не рекомендуется)
// Технически корректно, но стилистически плохо:
if (isLoggedIn)
    Console.WriteLine("Добро пожаловать!");

// С else:
if (isAdmin)
    Console.WriteLine("Режим администратора");
else
    Console.WriteLine("Обычный пользователь");

Почему это плохо? Три причины:

  • Хрупкость: легко добавить вторую строку и забыть поставить скобки — она выйдет из-под if
  • Неоднородность: в одном проекте стиль должен быть единым. Если ты пишешь со скобками в 99% случаев, то 1% без скобок — это нарушение стиля
  • Рефакторинг: когда ты перемещаешь код, легко потерять границы блока

💡 В официальных гайдлайнах Microsoft (Microsoft .NET Coding Conventions) рекомендуется всегда использовать фигурные скобки. Даже для одной строки. Мы следуем этому правилу во всех примерах курса.

🪆

Вложенные if (nested if)

Внутри if (или else) может быть другой if. Это называется вложенные условия. Они позволяют проверять несколько уровней условий.

C# · Вложенные if
int age = 25;
bool hasLicense = true;

// Внешнее условие: возраст
if (age >= 18)
{
    Console.WriteLine("Возраст подходит");

    // Внутреннее условие: наличие прав
    if (hasLicense)
    {
        Console.WriteLine("Права есть — можно арендовать машину");
    }
    else
    {
        Console.WriteLine("Нужны водительские права");
    }
}
else
{
    Console.WriteLine("Возраст не подходит для аренды");
}

Вложенные if могут быть любой глубины, но старайся не превышать 2-3 уровня. Более глубокие вложения трудно читать. В таких случаях лучше использовать логические операторы для объединения условий:

C# · Вложенные if vs логические операторы
// ❌ Глубокие вложения — трудно читать:
if (age >= 18)
{
    if (hasLicense)
    {
        if (hasMoney)
        {
            Console.WriteLine("Можно арендовать");
        }
    }
}

// ✅ Плоское условие — легко читать:
if (age >= 18 && hasLicense && hasMoney)
{
    Console.WriteLine("Можно арендовать");
}

// ✅ Или с ранним выходом:
if (age < 18) { Console.WriteLine("Возраст не подходит"); return; }
if (!hasLicense) { Console.WriteLine("Нет прав"); return; }
if (!hasMoney) { Console.WriteLine("Нет денег"); return; }
Console.WriteLine("Можно арендовать");
💡 Приём «ранний выход» (early return) — один из признаков хорошего кода. Вместо того чтобы вкладывать if, проверяй условия-препятствия и выходи (return) раньше. Основной код остаётся плоским.
❌

Типичные ошибки с if-else

1. Путаница = и ==

// ❌ Ошибка: присваивание вместо сравнения
if (x = 5) { ... }

// ✅ Правильно
if (x == 5) { ... }

В C# компилятор предупредит, но это не ошибка компиляции. Будь внимателен.

2. Точка с запятой после if

// ❌ Точка с запятой завершает if:
if (age >= 18);  // <-- if заканчивается здесь, с ; 
{
    Console.WriteLine("Совершеннолетний");
    // Этот блок не связан с if! Он выполняется всегда!
}

// ✅ Правильно:
if (age >= 18)
{
    Console.WriteLine("Совершеннолетний");
}

Обрати внимание: if (условие); — синтаксически корректно. Тело if — пустая инструкция. Блок {} — это просто блок кода, не связанный с if.

3. Неправильно понятый else

int score = 85;

// ❌ Так работает, но else относится к ближайшему if:
if (score >= 90)
    if (score == 100)
        Console.WriteLine("Идеально!");
else  // Этот else относится к if (score >= 90), а не к if (score == 100)!
    Console.WriteLine("Можно лучше");

// ✅ Со скобками всё очевидно:
if (score >= 90)
{
    if (score == 100)
    {
        Console.WriteLine("Идеально!");
    }
}
else
{
    Console.WriteLine("Можно лучше");
}

Проблема «dangling else» — else всегда относится к ближайшему if. Скобки решают проблему.

4. Избыточное сравнение с true/false

bool isActive = true;

// ❌ Избыточно:
if (isActive == true) { ... }
if (isActive == false) { ... }

// ✅ Лаконично:
if (isActive) { ... }       // уже равно true
if (!isActive) { ... }      // отрицание

if (isActive) читается как «если активно». if (isActive == true) — «если активно равно истине» — масло масляное.

5. Забыл преобразовать тип

string input = Console.ReadLine(); // всегда string
if (input > 18)  // ❌ Ошибка! string нельзя сравнить с числом
{ ... }

// ✅ Надо:
if (int.TryParse(input, out int age) && age > 18)
{ ... }

⚠️ Золотое правило: Если условие выглядит сложным — разбей его на части с понятными именами. Вместо if ((age >= 18 && hasTicket) || (age < 18 && hasParentalConsent)) напиши bool canEnter = (age >= 18 && hasTicket) || (age < 18 && hasParentalConsent); if (canEnter). Код станет понятным.

🧠

Логические принципы if-else

Есть несколько важных принципов, которые помогут писать чистые и правильные условия:

Принцип 1: «Положительное условие»

Проверяй позитивное условие, а не негативное. Человеческий мозг лучше понимает «если true, то...» чем «если не false, то...».

// ❌ Сложно:
if (!isBlocked) { ... }

// ✅ Легко:
if (isAllowed) { ... }

Принцип 2: «Счастливый путь»

Обрабатывай сначала нормальный (успешный) сценарий, а ошибки — в else или в ранних return.

// ❌ Ошибка на первом месте:
if (error != null) { Console.WriteLine(error); }
else { Console.WriteLine("Всё хорошо"); }

// ✅ Успех на первом месте:
if (error == null) { Console.WriteLine("Всё хорошо"); }
else { Console.WriteLine(error); }

Принцип 3: «Не повторяйся» (DRY)

Если в обеих ветках (if и else) есть одинаковый код — вынеси его наружу.

// ❌ Повтор:
if (isLoggedIn)
{
    Console.WriteLine("Проверка доступа...");
    Console.WriteLine("Добро пожаловать!");
}
else
{
    Console.WriteLine("Проверка доступа...");
    Console.WriteLine("Пожалуйста, войдите");
}

// ✅ Без повтора:
Console.WriteLine("Проверка доступа...");
if (isLoggedIn)
    Console.WriteLine("Добро пожаловать!");
else
    Console.WriteLine("Пожалуйста, войдите");
🧩

Всё вместе — симулятор банкомата

Программа «Банкомат». Используем все концепции if-else: вложенные условия, проверка баланса, лимитов, и авторизации.

C# · Симулятор банкомата
using System;

class Program
{
    static void Main()
    {
        // Данные аккаунта
        int pin = 1234;
        double balance = 5000.0;
        double dailyLimit = 10000.0;
        double withdrawnToday = 0.0;

        Console.Write("Введите PIN-код: ");
        string input = Console.ReadLine();

        // Проверка PIN
        if (int.TryParse(input, out int enteredPin))
        {
            if (enteredPin == pin)
            {
                Console.WriteLine("✅ PIN верный. Добро пожаловать!");

                Console.Write("Введите сумму для снятия: ");
                string amountInput = Console.ReadLine();

                if (double.TryParse(amountInput, out double amount))
                {
                    // Проверка: сумма положительная?
                    if (amount <= 0)
                    {
                        Console.WriteLine("❌ Сумма должна быть больше нуля.");
                    }
                    // Проверка: достаточно ли средств?
                    else if (amount > balance)
                    {
                        Console.WriteLine("❌ Недостаточно средств на счёте.");
                        Console.WriteLine($"Баланс: {balance} руб.");
                    }
                    // Проверка: не превышен ли дневной лимит?
                    else if (withdrawnToday + amount > dailyLimit)
                    {
                        Console.WriteLine("❌ Превышен дневной лимит.");
                        Console.WriteLine($"Остаток лимита: {dailyLimit - withdrawnToday} руб.");
                    }
                    // Всё хорошо — снимаем
                    else
                    {
                        balance -= amount;
                        withdrawnToday += amount;
                        Console.WriteLine($"✅ Возьмите деньги: {amount} руб.");
                        Console.WriteLine($"Остаток на счёте: {balance} руб.");
                    }
                }
                else
                {
                    Console.WriteLine("❌ Некорректная сумма. Введите число.");
                }
            }
            else
            {
                Console.WriteLine("❌ Неверный PIN-код!");
            }
        }
        else
        {
            Console.WriteLine("❌ PIN-код должен состоять из цифр.");
        }

        Console.WriteLine("Спасибо за использование банкомата!");
    }
}
💡 Обрати внимание: мы проверяем каждое условие последовательно. Сначала PIN, потом корректность суммы, потом баланс, потом лимит. Если любая проверка не пройдена — программа сообщает причину и завершается. Это называется «цепочка защитных проверок».
📝

Практическое задание

Напиши программу «Калькулятор доставки». Условия:

  • Спросить сумму заказа
  • Если сумма больше 3000 руб → доставка бесплатная
  • Если от 1500 до 3000 → доставка 300 руб
  • Если меньше 1500 → доставка 500 руб
  • Если покупатель — премиум-клиент (спросить yes/no) → скидка 10% на доставку
  • Если заказ больше 10000 → ещё и подарок (вывести "🎁")
  • Вывести итоговую сумму к оплате (заказ + доставка)
👀 Показать решение
using System;

class Program
{
    static void Main()
    {
        Console.Write("Введите сумму заказа: ");
        string orderInput = Console.ReadLine();

        if (!double.TryParse(orderInput, out double orderAmount) || orderAmount <= 0)
        {
            Console.WriteLine("Некорректная сумма заказа.");
            return;
        }

        Console.Write("Вы премиум-клиент? (да/нет): ");
        string premiumInput = Console.ReadLine().Trim().ToLower();
        bool isPremium = premiumInput == "да";

        // Расчёт доставки
        double deliveryCost;

        if (orderAmount > 3000)
        {
            deliveryCost = 0;
            Console.WriteLine("Доставка бесплатная!");
        }
        else if (orderAmount >= 1500)
        {
            deliveryCost = 300;
            Console.WriteLine("Доставка: 300 руб.");
        }
        else
        {
            deliveryCost = 500;
            Console.WriteLine("Доставка: 500 руб.");
        }

        // Скидка для премиум-клиентов
        if (isPremium && deliveryCost > 0)
        {
            double discount = deliveryCost * 0.1;
            deliveryCost -= discount;
            Console.WriteLine($"Скидка премиум-клиента: -{discount} руб.");
        }

        // Подарок
        if (orderAmount > 10000)
        {
            Console.WriteLine("🎁 Поздравляем! Вы получили подарок!");
        }

        double total = orderAmount + deliveryCost;
        Console.WriteLine($"{"=".PadRight(35, '=')}");
        Console.WriteLine($"Заказ:     {orderAmount} руб.");
        Console.WriteLine($"Доставка:  {deliveryCost} руб.");
        Console.WriteLine($"ИТОГО:     {total} руб.");
    }
}
📌

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

1️⃣
if (условие) { } — условие всегда bool. Если true — тело выполняется, если false — пропускается.
2️⃣
else — выполняется, когда условие if ложно. Выполнится ровно одна ветка: или if, или else.
3️⃣
Всегда ставь фигурные скобки { } — даже для одной строки. Это защищает от ошибок.
4️⃣
Вложенные if — if внутри if. Старайся не углубляться больше 2-3 уровней. Используй логические операторы для объединения.
5️⃣
Типичные ошибки: = вместо ==, точка с запятой после if (...);, висячий else, избыточное сравнение с true/false.
6️⃣
Принципы: положительное условие, счастливый путь, не повторяйся (DRY), ранний выход (early return).

Тест: 3.2: Оператор if-else

5 вопросов

Условный оператор

Premium