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

Урок 3.3 — Множественный выбор

Когда вариантов больше двух — цепочки if-else if-else и практика их применения.

В жизни редко бывает просто «да» или «нет». Чаще нужно выбрать один вариант из нескольких: «5» — отлично, «4» — хорошо, «3» — удовлетворительно, «2» — плохо, «1» — ужасно. В программировании для этого используется конструкция if → else if → else if → else.

🔀

Конструкция if → else if → else

Когда нужно проверить несколько условий и выполнить разные действия для каждого, используется цепочка else if. Синтаксис:

if (условие1) { } else if (условие2) { } else if (условие3) { } else { }

Важно понимать: else if — это не отдельная конструкция языка. Это просто else, внутри которого сразу написан if. То есть:

C# · else if — это else + if
// Так пишут (краткая форма):
if (x > 0)
    Console.WriteLine("Положительное");
else if (x < 0)
    Console.WriteLine("Отрицательное");
else
    Console.WriteLine("Ноль");

// Так это видит компилятор (полная форма):
if (x > 0)
    Console.WriteLine("Положительное");
else
{
    if (x < 0)
        Console.WriteLine("Отрицательное");
    else
        Console.WriteLine("Ноль");
}

Главное свойство цепочки else if: проверки выполняются сверху вниз, и как только одна из них даёт true — остальные пропускаются. Выполнится ровно одна ветка.

💡 Визуализируй это как эскалатор: ты входишь наверху, проезжаешь мимо этажей, и выходишь на том, где твоя остановка. Дальше не едешь.
📏

Порядок условий: это критически важно

В цепочке else if порядок имеет значение. Если два условия пересекаются, первое выигрывает. Рассмотрим классическую ошибку — определение оценки по баллам:

❌ Неправильный порядок

int score = 85;

if (score >= 50)       // 85 >= 50 → true!
    Console.WriteLine("Удовлетворительно");
else if (score >= 75)   // никогда не проверится
    Console.WriteLine("Хорошо");
else if (score >= 90)   // никогда не проверится
    Console.WriteLine("Отлично");
else
    Console.WriteLine("Неудовлетворительно");

// Вывод: "Удовлетворительно" — хотя 85 — это "Хорошо"!

Ошибка: мы поставили самое слабое условие первым. 85 >= 50 — true, поэтому цепочка остановилась. Нужно проверять от большего к меньшему.

✅ Правильный порядок

int score = 85;

if (score >= 90)       // 85 >= 90 → false
    Console.WriteLine("Отлично");
else if (score >= 75)   // 85 >= 75 → true!
    Console.WriteLine("Хорошо");
else if (score >= 50)
    Console.WriteLine("Удовлетворительно");
else
    Console.WriteLine("Неудовлетворительно");

// Вывод: "Хорошо" — правильно!

Проверяем от самого строгого условия к самому слабому. 85 не >= 90, но >= 75 — попадание.

Общее правило: в цепочке else if располагай условия от самого специфичного (самого строгого) к самому общему (самому слабому). Если условия не пересекаются — порядок не важен, но лучше всё равно придерживаться логики.

⚠️ Лайфхак: Когда пишешь цепочку условий, сначала продумай границы. Нарисуй числовую прямую: ====50====75====90==== и подумай, какой диапазон чему соответствует. Потом проверяй от большего к меньшему.

🎓

Практический пример: система оценок

Классический пример множественного выбора — перевод числовых баллов в буквенные оценки и текстовое описание:

C# · Система оценок
Console.Write("Введите количество баллов (0-100): ");
string input = Console.ReadLine();

if (int.TryParse(input, out int score))
{
    // Проверка на корректный диапазон
    if (score < 0 || score > 100)
    {
        Console.WriteLine("Ошибка: баллы должны быть от 0 до 100.");
    }
    // Цепочка else if — от строгого к слабому
    else if (score >= 90)
    {
        Console.WriteLine($"Баллы: {score} → Оценка: A (Отлично)");
        Console.WriteLine("Выдающиеся результаты!");
    }
    else if (score >= 75)
    {
        Console.WriteLine($"Баллы: {score} → Оценка: B (Хорошо)");
        Console.WriteLine("Хорошая работа, но есть куда расти.");
    }
    else if (score >= 60)
    {
        Console.WriteLine($"Баллы: {score} → Оценка: C (Удовлетворительно)");
        Console.WriteLine("Средний результат. Стоит подтянуть знания.");
    }
    else if (score >= 40)
    {
        Console.WriteLine($"Баллы: {score} → Оценка: D (Неудовлетворительно)");
        Console.WriteLine("Нужно серьёзно поработать.");
    }
    else
    {
        Console.WriteLine($"Баллы: {score} → Оценка: F (Провал)");
        Console.WriteLine("К сожалению, экзамен не сдан.");
    }
}
else
{
    Console.WriteLine("Ошибка: введите число.");
}
💡 Обрати внимание: сначала мы проверяем, что баллы в диапазоне 0-100. Это защитное программирование (defensive programming) — отсекаем некорректные входные данные до основной логики.
👶

Практический пример: возрастные группы

Ещё один частый сценарий — распределение по возрастным категориям:

C# · Возрастные группы
Console.Write("Сколько вам лет? ");
string ageInput = Console.ReadLine();

if (int.TryParse(ageInput, out int age) && age >= 0)
{
    string category;

    if (age <= 2)
    {
        category = "Младенец";
    }
    else if (age <= 12)
    {
        category = "Ребёнок";
    }
    else if (age <= 17)
    {
        category = "Подросток";
    }
    else if (age <= 35)
    {
        category = "Молодой взрослый";
    }
    else if (age <= 60)
    {
        category = "Взрослый";
    }
    else if (age <= 90)
    {
        category = "Пожилой";
    }
    else
    {
        category = "Долгожитель";
    }

    Console.WriteLine($"Вам {age} лет. Категория: {category}.");

    // Дополнительная логика — также через if, но это уже отдельные условия:
    if (age >= 18)
        Console.WriteLine("Вы совершеннолетний.");
    else
        Console.WriteLine("Вы несовершеннолетний.");

    if (age >= 65)
        Console.WriteLine("Вы на пенсии (по возрасту).");
}
else
{
    Console.WriteLine("Ошибка: введите корректный возраст.");
}
💡 Заметь: в этой цепочке else if каждое следующее условие неявно включает проверку предыдущих. Например, age <= 35 на самом деле означает age >= 18 && age <= 35, потому что предыдущие else if уже отсекли age < 18.
📅

Практический пример: день недели

Определяем день недели по числу (1-7) и даём рекомендацию:

C# · Дни недели
Console.Write("Введите номер дня недели (1-7): ");
string dayInput = Console.ReadLine();

if (int.TryParse(dayInput, out int day) && day >= 1 && day <= 7)
{
    string name;
    string recommendation;

    if (day == 1)
    {
        name = "Понедельник";
        recommendation = "Начни неделю с плана!";
    }
    else if (day == 2)
    {
        name = "Вторник";
        recommendation = "Работай над проектом.";
    }
    else if (day == 3)
    {
        name = "Среда";
        recommendation = "Середина недели — держись!";
    }
    else if (day == 4)
    {
        name = "Четверг";
        recommendation = "Почти пятница!";
    }
    else if (day == 5)
    {
        name = "Пятница";
        recommendation = "🎉 Ура, пятница!";
    }
    else if (day == 6)
    {
        name = "Суббота";
        recommendation = "Отдыхай и набирайся сил.";
    }
    else  // day == 7
    {
        name = "Воскресенье";
        recommendation = "Готовься к новой неделе.";
    }

    Console.WriteLine($"{name}: {recommendation}");

    // Дополнительная классификация (отдельный if, не цепочка):
    if (day <= 5)
        Console.WriteLine("Будний день — работаем! 💼");
    else
        Console.WriteLine("Выходной — отдыхаем! 🏖️");
}
else
{
    Console.WriteLine("Ошибка: введите число от 1 до 7.");
}
💡 Для проверки набора фиксированных значений (1..7) лучше использовать switch — мы изучим его в уроке 3.5. Но if-else со сравнениями == тоже работает отлично.
⚖️

Когда использовать else if vs несколько if

Это один из ключевых вопросов в понимании условий. Разница между else if и несколькими отдельными if — в исключительности.

Характеристика else if Несколько if
ВыполняетсяТолько одна веткаМожет выполниться несколько
ВзаимоисключениеДа (варианты не пересекаются)Нет (можно попасть в несколько)
ПроизводительностьЛучше (останавливается на первом true)Хуже (всегда проверяет все)
Когда использоватьОдин выбор из многихНезависимые проверки

✅ Когда использовать else if: взаимоисключающие варианты

Пользователь может быть в одной возрастной группе. Не может быть одновременно «ребёнком» и «взрослым».

// Только одна категория может быть true:
if (age < 12) ...
else if (age < 18) ...
else if (age < 60) ...
else ...

✅ Когда использовать несколько if: независимые проверки

Пользователь может быть одновременно и «совершеннолетним», и «премиум-клиентом», и «иметь скидку».

// Каждое условие проверяется независимо:
if (age >= 18) Console.WriteLine("Взрослый");
if (isPremium) Console.WriteLine("Премиум");
if (hasDiscount) Console.WriteLine("Скидка");
// Могут выполниться все три, если все true!

❌ Типичная ошибка: несколько if вместо else if

int score = 85;

// ❌ Каждый if проверяется независимо!
if (score >= 90) Console.WriteLine("Отлично");     // false
if (score >= 75) Console.WriteLine("Хорошо");      // true
if (score >= 50) Console.WriteLine("Удовлетворительно"); // true!

// Вывод:
// Хорошо
// Удовлетворительно — ЛИШНЕЕ!

// ✅ Правильно: используем else if
if (score >= 90) Console.WriteLine("Отлично");
else if (score >= 75) Console.WriteLine("Хорошо");
else if (score >= 50) Console.WriteLine("Удовлетворительно");

// Вывод: только "Хорошо"

Если варианты взаимоисключающие — используй else if. Иначе ты можешь получить несколько выводов, где нужен один.

❌

Типичные ошибки с множественным выбором

1. Неправильный порядок условий (пересечение)

Условия пересекаются, и более общее перехватывает более частное.

int x = 50;
if (x > 0)          // true — остальные не проверятся!
    Console.WriteLine("Положительное");
else if (x > 100)    // никогда
    Console.WriteLine("Больше 100");
else if (x == 50)    // никогда
    Console.WriteLine("Ровно 50");
// Правильный порядок: от более строгих к более общим.

2. Забытый else на конце

Если все else if оказались false — без else ничего не выполнится. Иногда это ок, но часто — ошибка.

if (age < 0)
    Console.WriteLine("Некорректный возраст");
else if (age < 18)
    Console.WriteLine("Несовершеннолетний");
else if (age < 100)
    Console.WriteLine("Взрослый");
// ❌ Если age = 200 — ничего не выведется! Нет else.

3. Избыточные проверки в else if

Повторная проверка того, что уже неявно проверено.

if (age >= 18) { }
else if (age < 18 && age >= 12) { } // ❌ age < 18 — лишняя проверка
else if (age < 12) { }                // мы уже знаем, что age < 12

// ✅ Лаконично:
if (age >= 18) { }
else if (age >= 12) { } // неявно: age >= 12 && age < 18
else { }                 // неявно: age < 12

4. Глубокие вложения вместо else if

Вложение вместо плоской цепочки.

// ❌ Глубокие вложения:
if (score >= 50)
{
    if (score >= 75)
    {
        if (score >= 90)
            Console.WriteLine("Отлично");
        else
            Console.WriteLine("Хорошо");
    }
    else
        Console.WriteLine("Удовлетворительно");
}
else
    Console.WriteLine("Неуд");

// ✅ Плоская цепочка else if:
if (score >= 90) Console.WriteLine("Отлично");
else if (score >= 75) Console.WriteLine("Хорошо");
else if (score >= 50) Console.WriteLine("Удовлетворительно");
else Console.WriteLine("Неуд");

⚠️ Золотое правило: Сначала проверяй самые специфичные (узкие) условия. Используй else if для взаимоисключающих вариантов. Всегда добавляй else в конце для «ловли всего остального». Если else не нужен — хотя бы добавь комментарий, почему.

🧩

Всё вместе — классификатор налогов

Программа «Калькулятор налога» с прогрессивной ставкой. Используем множественный выбор, защитное программирование и независимые проверки.

C# · Калькулятор налога
using System;

class Program
{
    static void Main()
    {
        Console.Write("Введите ваш годовой доход (руб.): ");
        string incomeInput = Console.ReadLine();

        if (!double.TryParse(incomeInput, out double income) || income < 0)
        {
            Console.WriteLine("Ошибка: введите положительное число.");
            return;
        }

        // ——— Множественный выбор: налоговая ставка ———
        // Прогрессивная шкала налога
        double taxRate;     // ставка в процентах
        string taxBracket;  // название категории

        if (income <= 0)
        {
            // Этот случай уже отсечён TryParse, но на всякий случай:
            taxRate = 0;
            taxBracket = "Нет дохода";
        }
        else if (income <= 500_000)
        {
            taxRate = 5;
            taxBracket = "Низкий доход";
        }
        else if (income <= 1_500_000)
        {
            taxRate = 10;
            taxBracket = "Средний доход";
        }
        else if (income <= 5_000_000)
        {
            taxRate = 15;
            taxBracket = "Высокий доход";
        }
        else
        {
            taxRate = 20;
            taxBracket = "Очень высокий доход";
        }

        // ——— Независимые проверки ———
        // Они не взаимоисключающие, поэтому используем if, не else if
        string status = "";

        if (income < 200_000)
            status += "Можно получить налоговый вычет. ";

        if (income > 2_000_000)
            status += "Рекомендуем обратиться к налоговому консультанту. ";

        if (income > 10_000_000)
            status += "Поздравляем, вы в top 1%!";

        // ——— Расчёт ———
        double taxAmount = income * (taxRate / 100.0);
        double afterTax = income - taxAmount;

        // ——— Вывод ———
        Console.WriteLine($"{"=".PadRight(45, '=')}");
        Console.WriteLine($"  Налоговый расчёт");
        Console.WriteLine($"{"=".PadRight(45, '=')}");
        Console.WriteLine($"  Доход:       {income:N2} руб.");
        Console.WriteLine($"  Категория:   {taxBracket}");
        Console.WriteLine($"  Ставка:      {taxRate}%");
        Console.WriteLine($"  Налог:       {taxAmount:N2} руб.");
        Console.WriteLine($"  После налогов: {afterTax:N2} руб.");
        if (!string.IsNullOrEmpty(status))
        {
            Console.WriteLine($"{"=".PadRight(45, '=')}");
            Console.WriteLine($"  {status}");
        }
    }
}
💡 Обрати внимание на разделение: else if для взаимоисключающих категорий (налоговая ставка) и независимые if для дополнительных статусов. Это чёткая архитектура: одна цепочка — один выбор.
📝

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

Напиши программу «Конвертер валют». Условия:

  • Спросить сумму в рублях
  • Спросить валюту для конвертации (USD, EUR, CNY, KZT, TRY)
  • Использовать else if для выбора курса (задай свои курсы)
  • Если валюта не распознана — вывести ошибку
  • Если сумма больше 1 000 000 руб — вывести предупреждение о контроле ЦБ
  • Вывести результат с двумя знаками после запятой
👀 Показать решение
using System;

class Program
{
    static void Main()
    {
        Console.Write("Введите сумму в рублях: ");
        string rubInput = Console.ReadLine();

        if (!double.TryParse(rubInput, out double rubles) || rubles <= 0)
        {
            Console.WriteLine("Ошибка: введите корректную сумму.");
            return;
        }

        Console.Write("Введите валюту (USD, EUR, CNY, KZT, TRY): ");
        string currency = Console.ReadLine().Trim().ToUpper();

        // ——— Множественный выбор курса ———
        double rate = 0;
        string currencyName = "";

        if (currency == "USD")
        {
            rate = 92.50;
            currencyName = "долларов США";
        }
        else if (currency == "EUR")
        {
            rate = 100.20;
            currencyName = "евро";
        }
        else if (currency == "CNY")
        {
            rate = 12.80;
            currencyName = "юаней";
        }
        else if (currency == "KZT")
        {
            rate = 0.19;
            currencyName = "тенге";
        }
        else if (currency == "TRY")
        {
            rate = 2.85;
            currencyName = "лир";
        }
        else
        {
            Console.WriteLine("Ошибка: неизвестная валюта. Доступны: USD, EUR, CNY, KZT, TRY.");
            return;
        }

        double result = rubles / rate;

        // Независимая проверка на крупную сумму:
        if (rubles > 1_000_000)
        {
            Console.WriteLine("⚠️ Внимание: операции на сумму свыше 1 млн руб.");
            Console.WriteLine("   могут быть проверены ЦБ РФ.");
        }

        Console.WriteLine($"{"=".PadRight(40, '=')}");
        Console.WriteLine($"{rubles:N2} руб. = {result:N2} {currencyName}");
        Console.WriteLine($"Курс: 1 {currency} = {rate} руб.");
    }
}
📌

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

1️⃣
if → else if → else — цепочка для взаимоисключающих вариантов. Выполнится ровно одна ветка.
2️⃣
Порядок важен! Проверяй от самого строгого/специфичного условия к самому общему. Иначе более общее «перехватит» частный случай.
3️⃣
else if vs несколько if: else if — один выбор из многих (взаимоисключение). Несколько if — независимые проверки (могут все выполниться).
4️⃣
Не повторяй проверки в else if. Каждое следующее условие неявно включает отрицание предыдущих.
5️⃣
Всегда добавляй else в конце для «всех остальных случаев». Если не нужен — хотя бы закомментируй намерение.
6️⃣
Практические примеры: оценки по баллам, возрастные группы, дни недели, налоговые ставки, конвертер валют — всё это else if.

Тест: 3.3: Множественный выбор

5 вопросов

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

Premium