Тернарный и другие операторы ветвления в C: if, else, switch и ?:

Тернарный и другие операторы ветвления в C: if, else, switch и ?: Полезное

Ветвление — это выбор одного из нескольких путей выполнения программы в зависимости от условия. В языке C ветвление задают четыре конструкции: оператор if, пара if-else, оператор выбора switch и тернарный оператор ?:. Тернарный оператор — это сокращенная запись if-else, которая не выполняет действие, а возвращает значение.

Ниже разберем каждую конструкцию: синтаксис, когда ее применять и чем она отличается от соседних. Все примеры — законченные программы, я прогнал их компилятором, вывод в блоках после кода реальный. Проверено на Apple clang (C17) 17.09.2026; конструкции ветвления в C и C++ совпадают, поэтому примеры справедливы и для C++.

Оператор if: одна ветвь

Оператор if выполняет блок кода, только если условие истинно. В C нет отдельного логического типа в старом смысле: истиной считается любое ненулевое значение, ложью — ноль. Условие в скобках вычисляется, и если результат не равен нулю, выполняется блок в фигурных скобках.

#include <stdio.h>

int main(void) {
    int temperature = 30;

    if (temperature > 25) {
        printf("Жарко, включаем вентилятор\n");
    }

    printf("Программа продолжает работу\n");
    return 0;
}

Вывод программы:

Жарко, включаем вентилятор
Программа продолжает работу

Сравнение temperature > 25 дает истину, поэтому строка про вентилятор печатается. Если бы температура была меньше, блок if пропустился бы, а выполнение сразу перешло к следующей строке после него.

Фигурные скобки можно опустить, когда в ветви ровно одна инструкция. Делать так не стоит: при добавлении второй строки легко получить ошибку, потому что к if относится только первая инструкция, а вторая выполнится безусловно.

Двойное ветвление: if-else

Конструкция if-else задает два взаимоисключающих пути: один блок выполняется при истинном условии, другой — при ложном. Ровно один из блоков отработает всегда.

#include <stdio.h>

int main(void) {
    int number = 7;

    if (number % 2 == 0) {
        printf("%d - четное\n", number);
    } else {
        printf("%d - нечетное\n", number);
    }
    return 0;
}

Вывод программы:

7 - нечетное

Остаток от деления 7 % 2 равен единице, условие ложно, поэтому управление уходит в ветвь else. Такая пара удобна, когда нужно развести ровно два случая: четное или нечетное, доступ разрешен или запрещен, есть скидка или нет.

Множественное ветвление: лестница else if

Когда вариантов больше двух, ветви объединяют в лестницу else if. Условия проверяются сверху вниз; срабатывает первое истинное, остальные пропускаются. Завершающий else (без условия) ловит все случаи, которые не подошли ни под одну проверку.

#include <stdio.h>

int main(void) {
    int score = 82;

    if (score >= 90) {
        printf("Оценка: отлично\n");
    } else if (score >= 75) {
        printf("Оценка: хорошо\n");
    } else if (score >= 60) {
        printf("Оценка: удовлетворительно\n");
    } else {
        printf("Оценка: неудовлетворительно\n");
    }
    return 0;
}

Вывод программы:

Оценка: хорошо

Значение 82 не прошло первую проверку (не >= 90), но прошло вторую (>= 75), поэтому выбрана ветвь «хорошо», а условие score >= 60 уже не проверялось. Порядок условий здесь важен: если поставить score >= 60 первым, оно перехватит и отличников, и хорошистов. В лестнице условия идут от самого строгого к самому мягкому.

Оператор switch: выбор по значению

switch выбирает ветвь по точному совпадению значения выражения с константой в case. Он удобнее лестницы else if, когда сравнивается одна переменная с набором конкретных значений. После совпавшего case выполнение идет вниз до break, который выходит из switch.

#include <stdio.h>

int main(void) {
    int day = 3;

    switch (day) {
        case 1:
            printf("Понедельник\n");
            break;
        case 3:
            printf("Среда\n");
            break;
        case 5:
            printf("Пятница\n");
            break;
        default:
            printf("Другой день\n");
    }
    return 0;
}

Вывод программы:

Среда

Значение day равно 3, совпал второй case, напечаталась «Среда», а break завершил switch. Ветвь default необязательна и срабатывает, когда ни одна константа не подошла. В case допустимы только целочисленные константы (значения типов int, char, unsigned и перечислений), но не диапазоны и не переменные.

Ловушка: забытый break

Без break после совпавшего case выполнение «проваливается» в следующие ветви — это называют fall-through. Иногда так делают намеренно, но чаще это ошибка. Вот что печатает switch без break:

#include <stdio.h>

int main(void) {
    int grade = 2;

    switch (grade) {
        case 2:
            printf("Двойка\n");
        case 3:
            printf("Тройка\n");
        default:
            printf("Оценка обработана\n");
    }
    return 0;
}

Вывод программы:

Двойка
Тройка
Оценка обработана

Совпал case 2, но из-за отсутствия break выполнились и case 3, и default. Исправление — поставить break в конце каждой ветви, тогда напечатается только «Двойка».

Тернарный оператор ?:

Тернарный оператор — единственный в C оператор с тремя операндами. Его форма: условие ? значение_если_истина : значение_если_ложь. Он не выполняет блок кода, а вычисляет и возвращает одно из двух значений, поэтому его можно подставлять прямо в выражение или присваивание.

#include <stdio.h>

int main(void) {
    int a = 15, b = 42;

    int max = (a > b) ? a : b;
    printf("Максимум: %d\n", max);

    int n = 7;
    printf("Число %d %s\n", n, (n % 2 == 0) ? "четное" : "нечетное");
    return 0;
}

Вывод программы:

Максимум: 42
Число 7 нечетное

В первом случае (a > b) ложно, поэтому в max попадает b, то есть 42. Во втором тернарный оператор выбирает подходящую строку прямо внутри printf. Тем же if-else это заняло бы четыре-пять строк, а тернарный оператор — одну.

Главное ограничение: ветви тернарного оператора — это значения, а не наборы действий. Если в каждой ветке нужно выполнить несколько инструкций или вызвать функции с побочными эффектами, читаемее обычный if-else. Вкладывать тернарные операторы друг в друга тоже не стоит — выражение быстро становится нечитаемым.

Как выбрать конструкцию

Все четыре конструкции решают одну задачу — ветвление, но подходят под разные ситуации.

Конструкция Когда применять
if одно действие при выполнении условия, альтернатива не нужна
if-else ровно два взаимоисключающих пути
лестница else if больше двух случаев, особенно с диапазонами и разными условиями
switch одна переменная сравнивается с набором конкретных целых или символьных значений
?: нужно вернуть одно из двух значений внутри выражения, а не выполнять блоки

Практическое правило: если сравнивается одна величина с фиксированными значениями — берите switch, он нагляднее длинной лестницы. Если условия разные или это диапазоны — лестница else if. Если результат — это выбор значения для присваивания или аргумента, короче всего тернарный оператор.

Частая ошибка: = вместо ==

Самая известная ошибка в условиях C — написать одиночное = (присваивание) вместо == (сравнение). Компилятор такой код принимает: if (x = 0) сначала присваивает x ноль, а потом проверяет полученное значение, которое равно нулю, то есть ложь.

#include <stdio.h>

int main(void) {
    int x = 5;

    if (x = 0) {
        printf("x равен нулю\n");
    } else {
        printf("x не ноль, стало: %d\n", x);
    }
    return 0;
}

Вывод программы:

x не ноль, стало: 0

Условие «сработало наоборот»: ветвь if пропущена, а переменная x молча обнулилась. Исправление — сравнение через двойное равно: if (x == 0). Многие компиляторы предупреждают о присваивании в условии (у clang и gcc это предупреждение -Wparentheses), но по умолчанию это не ошибка, и программа собирается.

Выводы

  • Ветвление в C задают четыре конструкции: if, if-else, лестница else if и switch, плюс тернарный оператор ?: как выражение.
  • Истина в условии — любое ненулевое значение, ложь — ноль; отсюда и ловушка if (x = 0).
  • switch сравнивает одну переменную с целочисленными константами; забытый break дает проваливание в соседние ветви.
  • Тернарный оператор возвращает значение, а не выполняет блоки, и заменяет короткий if-else в одну строку.

Где применяется и что учить дальше

Ветвление — базовый механизм, без которого не обходится ни одна программа: проверка ввода, выбор алгоритма по данным, обработка меню и состояний. Те же if, switch и ?: без изменений работают в C++, поэтому, освоив их в C, вы сразу применяете их и в более крупных проектах на C++.

Освойте тему на практике

Разобрать синтаксис C++ системно, от операторов и типов до функций и первых программ, помогает базовый курс по C++ в Otus. Оценить формат и уровень до старта можно на бесплатных открытых уроках Otus — это живые занятия с преподавателями.

Смежные темы: Условные операторы в C, Python и его операторы.

FAQ

Можно ли в case у switch указать диапазон значений или переменную? В стандартном C — нет: после case допустима только целочисленная константа или константное выражение. Для диапазонов и сравнений с переменными используют лестницу else if.

Чем тернарный оператор отличается от if-else по сути? Тернарный оператор — это выражение, он возвращает значение и подставляется внутрь другого выражения. if-else — это оператор: он управляет выполнением блоков, но сам значения не возвращает.

Обязательна ли ветка default в switch и else в лестнице? Нет, обе необязательны. Но их полезно добавлять, чтобы явно обработать случай, не подошедший ни под одно условие, — иначе такой ввод молча останется без реакции.

OTUS Журнал
Бесплатные открытые уроки (поп-ап)