JavaRush /Курсы /C++ SELF /Условный оператор: if/else

Условный оператор: if/else

C++ SELF
3 уровень , 2 лекция
Открыта

1. Синтаксис ветвлений: if, else, else if

Когда вы только начинаете программировать, кажется, что программа — это просто калькулятор: ввели числа, получили ответ. Но довольно быстро выясняется, что реальная программа почти всегда «ветвится»: если пользователь ввёл одно — делаем так, если другое — иначе. Даже в стандарте C++ отдельно выделяют понятие condition («условие») как важную часть управляющих конструкций вроде if.

Самая простая мысль на сегодня: if — это как развилка на дороге. Условие — это вопрос, на который программа отвечает true или false, и выбирает одну из веток.

Прежде чем лепить «умные» условия, важно навести порядок в голове: if — это не магия, а очень строгая конструкция. В скобках после if должно быть выражение типа bool (или то, что к нему приводится), а дальше идёт команда или блок команд. И вот тут начинается первая битва новичка с синтаксисом: где скобки круглые, где фигурные, и почему одна лишняя точка с запятой ; ломает смысл.

Базовый if: «если (…) то …»

Мини-скелет выглядит так:

if (condition) {
    // действия, если condition == true
}
Базовая форма if

Пример: «совершеннолетний или нет»

Сделаем очень прямолинейно: вводим возраст и печатаем статус.

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    if (age >= 18) {
        std::cout << "adult\n"; // например, при вводе 18 -> adult
    }
}

Здесь важно прочувствовать: age >= 18 — это выражение, которое вычисляется в true или false. Если оно true, выполняется блок.

else: «иначе делаем вот это»

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

Базовая форма:

if (condition) {
    // true-ветка
} else {
    // false-ветка
}
Полная развилка if / else

И это уже полноценная развилка «налево/направо».

Пример: «adult/minor»

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    if (age >= 18) {
        std::cout << "adult\n"; // 18 -> adult
    } else {
        std::cout << "minor\n"; // 17 -> minor
    }
}

Обратите внимание на читабельность: две ветки почти как два абзаца текста. Это именно то, к чему мы стремимся: код должен читаться глазами, а не угадываться как ребус.

else if: «иначе если … иначе если … иначе …»

Теперь переходим к части, где нужно выбрать одну ветку из нескольких. Это суперчастая ситуация: число может быть положительным/отрицательным/нулём, команда может быть "add"/"remove"/"exit", оценка может быть «отлично/хорошо/удовлетворительно/плохо».

Цепочка выглядит так:

if (cond1) {
    ...
} else if (cond2) {
    ...
} else if (cond3) {
    ...
} else {
    ...
}

Правило дня: в такой цепочке выполнится ровно одна ветка — первая подходящая сверху вниз.

Пример: знак числа

#include <iostream>

int main() {
    int x = 0;
    std::cin >> x;

    if (x > 0) {
        std::cout << "positive\n"; // 5 -> positive
    } else if (x < 0) {
        std::cout << "negative\n"; // -3 -> negative
    } else {
        std::cout << "zero\n";     // 0 -> zero
    }
}

Почему порядок важен? Потому что проверки идут сверху вниз. Если бы мы по ошибке написали x >= 0 первой строкой, то ветка else if (x < 0) стала бы почти бесполезной: всё, что не отрицательное, уже «съелось» бы первой проверкой.

3. Читаемость ветвлений: {}, уровни смысла и имена проверок

Есть две категории новичков: те, кто ставит {} всегда, и те, кто однажды потерял два часа из‑за отсутствующих {} — и потом тоже стал ставить всегда.

Формально C++ разрешает писать так:

if (condition)
    std::cout << "Hello\n";

Но для начинающего это как кататься на велосипеде без рук: кто-то умеет, но мы пока учимся ездить, а не впечатлять прохожих.

Почему «одна строка без {}» опасна

Проблема появляется, когда вы сначала написали одну строку, а потом добавили вторую и забыли скобки. Код компилируется, но делает «что-то странное».

Сравните:

// ПЛОХО: легко сломать при добавлении строк
if (age >= 18)
    std::cout << "adult\n";
    std::cout << "welcome!\n"; // выполняется ВСЕГДА

и

// ХОРОШО: структура всегда очевидна
if (age >= 18) {
    std::cout << "adult\n";
    std::cout << "welcome!\n";
}

Вторая версия буквально визуально говорит: «эти две строки — одно действие для ветки».

else if и вложенный if: это разные смыслы

Очень частая путаница: «а можно я просто вложу if внутрь if?» Можно. Но смысл будет другой. И если смысл другой — лучше писать так, чтобы читатель (включая вас через неделю) сразу это увидел.

else if — это «выбор одной ветки из набора взаимоисключающих вариантов».

Вложенный if — это «мы уже выбрали ветку, и внутри неё уточняем».

Пример: где нужен вложенный if

Допустим: сначала проверяем, что возраст вообще корректный (не отрицательный), а уже потом решаем adult/minor.

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    if (age < 0) {
        std::cout << "invalid\n";      // -5 -> invalid
    } else {
        if (age >= 18) {
            std::cout << "adult\n";    // 20 -> adult
        } else {
            std::cout << "minor\n";    // 7 -> minor
        }
    }
}

Смысл тут такой: «если возраст плохой — сразу invalid; иначе решаем взрослый/ребёнок».

Если попытаться это «впихнуть» в одну цепочку else if, тоже получится, но новичку обычно сложнее читать, потому что смешиваются разные уровни смысла: валидность данных и классификация данных.

Делайте условия читаемыми: называйте проверки

В этой лекции мы говорим не только «как работает if», но и «как сделать так, чтобы ваш код не выглядел как шифр». Очень простой приём — вынести часть проверки в переменную типа bool с нормальным именем.

Это не «лишние переменные», а подписи на проводах. Без подписи можно тоже подключить, но потом ремонтировать больно.

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    bool is_adult = (age >= 18);

    if (is_adult) {
        std::cout << "adult\n";
    } else {
        std::cout << "minor\n";
    }
}

Плюс такого подхода: условие if (is_adult) читается почти как английское предложение. Минус: нужно придумать имя. Но это «минус» только первые пару недель, потом мозг начинает делать это автоматически.

4. Практический мини‑пример: «обработчик команды» без циклов

Сейчас мы соберём маленькую заготовку приложения, которое будет развиваться дальше по курсу. Пока без циклов (мы их ещё не проходили), поэтому программа обработает одну команду и завершится. Но даже в таком виде она уже будет похожа на реальный консольный интерфейс: пользователь вводит команду, программа выбирает, что делать.

Идея простая: читаем строку cmd и делаем разные действия.

Версия 1: три команды

#include <iostream>
#include <string>

int main() {
    std::string cmd;
    std::cin >> cmd;

    if (cmd == "hello") {
        std::cout << "Hello!\n";           // hello -> Hello!
    } else if (cmd == "help") {
        std::cout << "Commands: hello, help, exit\n";
    } else if (cmd == "exit") {
        std::cout << "Bye!\n";             // exit -> Bye!
    } else {
        std::cout << "Unknown command\n";  // qwerty -> Unknown command
    }
}

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

Версия 2: команда с числом

Пусть команда будет "age", и после неё пользователь вводит число. Мы не делаем сейчас сложных проверок ввода (это будет отдельно), но покажем, как ветка if может содержать свой маленький сценарий.

#include <iostream>
#include <string>

int main() {
    std::string cmd;
    std::cin >> cmd;

    if (cmd == "age") {
        int age = 0;
        std::cin >> age;

        if (age >= 18) {
            std::cout << "adult\n"; // age 20 -> adult
        } else {
            std::cout << "minor\n"; // age 7 -> minor
        }
    } else {
        std::cout << "Try command: age\n";
    }
}

Обратите внимание: внутри ветки cmd == "age" мы делаем ещё одно ветвление. Это нормальная и очень жизненная история: «сначала выбираем режим, потом внутри режима выбираем действие».

Небольшая схема: как выполняется if / else if / else

Иногда полезно увидеть else if не как «магические слова», а как простой алгоритм: проверили первое — если да, выполнили и ушли; если нет, пошли дальше.

flowchart TD
    A[Начало] --> B{cond1?}
    B -->|да| C[ветка 1]
    B -->|нет| D{cond2?}
    D -->|да| E[ветка 2]
    D -->|нет| F{cond3?}
    F -->|да| G[ветка 3]
    F -->|нет| H[else-ветка]
    C --> Z[Конец]
    E --> Z
    G --> Z
    H --> Z

Эта схема полезна тем, что объясняет главный факт дня: выполняется только одна ветка, и проверка идёт сверху вниз.

5. Типичные ошибки при работе с if/else

Ошибка №1: точка с запятой после if.
Новички иногда пишут if (cond); — и это выглядит почти правильно, но смысл ломается полностью. Точка с запятой — это «пустая команда»: условие проверилось, а дальше «ничего не сделали». Блок после этого выполняется уже как обычный блок, то есть почти всегда. Если видите странное поведение «ветка выполняется всегда», первым делом ищите лишний ;.

Ошибка №2: ветки без {} и «убежавшая строка».
Сначала всё работает: в ветке одна строка. Потом вы добавили вторую, но забыли фигурные скобки, и вторая строка стала выполняться всегда (или никогда) — в зависимости от того, куда она попала. Это одна из самых обидных ошибок: компилятор не ругается, а логика уже другая. Привычка «всегда ставить {}» лечит это почти на 100%.

Ошибка №3: перепутали смысл else if и вложенного if.
Если вам нужно выбрать «один вариант из многих» — используйте цепочку else if. Если вам нужно «сначала проверить одно, а внутри уже уточнить другое» — используйте вложенный if. Когда эти смыслы смешиваются, код становится трудным для чтения: вроде бы работает, но непонятно, что автор хотел сказать.

Ошибка №4: плохой порядок проверок в цепочке else if.
Проблема появляется, когда первая проверка слишком «широкая» и перехватывает случаи, которые должны были попасть в нижние ветки. Например, if (x >= 0) перед else if (x == 0) — и ветка x == 0 никогда не выполнится. Лечится простым правилом: сначала более специфичные случаи, потом более общие (или продумываем «лестницу» сверху вниз словами и только потом пишем код).

Ошибка №5: длинные ветки и «потеря смысла».
Иногда начинающий пишет в каждой ветке по 40 строк. Формально это нормально, но читать тяжело: вы забываете, какое условие выбрало ветку, пока долистали до конца. На этом этапе курса мы не разбираем функции, поэтому рецепт простой: держите ветки короткими, печатайте понятные сообщения, а условия делайте максимально ясными. Когда появятся функции, мы научимся «утончать main», но пока тренируем аккуратный стиль прямо здесь.

1
Задача
C++ SELF, 3 уровень, 2 лекция
Недоступна
Возрастной контроль
Возрастной контроль
1
Задача
C++ SELF, 3 уровень, 2 лекция
Недоступна
Прогноз погоды
Прогноз погоды
1
Задача
C++ SELF, 3 уровень, 2 лекция
Недоступна
Команда терминала
Команда терминала
1
Задача
C++ SELF, 3 уровень, 2 лекция
Недоступна
Тариф доставки
Тариф доставки
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ