Перейти к содержимому
Теория · Условия · урок 1 из 6

if, else и if с инициализатором

Инструкции в main выполняются по порядку, сверху вниз. Инструкция if выполняет блок в фигурных скобках, только если условие в круглых скобках истинно. Блок после else выполняется, когда условие ложно:

C++
#include <iostream>

int main() {
    int t = 25;
    if (t < 0) {
        std::cout << "frost\n";
    } else if (t < 20) {
        std::cout << "cool\n";
    } else {
        std::cout << "warm\n";  // warm
    }
}

Каждый такой блок называют веткой (branch). Цепочка else if проверяет условия сверху вниз и выполняет первую ветку, чьё условие истинно, а остальные пропускает. Ветка else в конце срабатывает, когда ложны все условия. Без неё в этом случае не выполнится ничего.

Висячий else

Фигурные скобки вокруг ветки из одной инструкции можно не писать. Но когда два if вложены друг в друга без скобок, else можно по ошибке приписать не тому if. Компилятор (compiler) относит else к ближайшему if, у которого ещё нет своего else, а на отступы не смотрит:

C++
int x = 5;
if (x > 0)
    if (x > 10)
        std::cout << "big\n";
else  // ✗
    std::cout << "not positive\n";  // not positive

По отступам else принадлежит if (x > 0), но на деле он достался if (x > 10). Поэтому при x = 5 программа печатает not positive. Такой else называют висячим (dangling else). Clang и GCC предупреждают о нём, но код компилируется.

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

if с инициализатором

Переменную, нужную только для проверки, можно объявить прямо в if — перед условием, через точку с запятой. Эту часть if называют инициализатором (initializer). Объявленная в нём переменная видна в условии и во всех ветках этого if:

C++
int n = 2023;
if (int r = n % 4; r == 0) {
    std::cout << "divisible by 4\n";
} else {
    std::cout << "remainder " << r << '\n';  // remainder 3
}

После if переменной r уже нет: обращение к ней ниже не скомпилируется. Поэтому имя r не мешает остальному коду функции.

Частая ошибка

К ветке без фигурных скобок дописали вторую строку с тем же отступом:

C++
int x = -1;
if (x > 0)
    std::cout << "positive\n";
    std::cout << "checked\n";  // ✗
TEXT
warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]

Без скобок if управляет только одной следующей инструкцией, и отступ этого не меняет. Поэтому checked печатается при любом x, в том числе при x = -1. Компилятор лишь предупреждает и собирает программу. Исправление — фигурные скобки вокруг обеих строк.