Оператор switch в C++: case, break и default с примерами

Как работает switch в C++: синтаксис, метки case, зачем нужен break, что делает default, какие типы можно проверять и какие ошибки чаще всего допускают новички.

Содержание

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

Синтаксис switch

C++
switch (выражение) {
    case значение1:
        // код для значения1
        break;
    case значение2:
        // код для значения2
        break;
    default:
        // код для всех остальных значений
}

Программа вычисляет выражение в скобках один раз, находит метку case с таким же значением и продолжает выполнение с неё. Если подходящей метки нет, выполняется ветка default. Если нет и её, switch не делает ничего.

Пример: день недели

C++
#include <iostream>

int main() {
    int day;
    std::cin >> day;

    switch (day) {
        case 1:
            std::cout << "Понедельник\n";
            break;
        case 2:
            std::cout << "Вторник\n";
            break;
        case 3:
            std::cout << "Среда\n";
            break;
        default:
            std::cout << "Другой день\n";
    }
}

Для числа 2 программа выведет «Вторник», для числа 7 — «Другой день».

Зачем нужен break

break завершает switch. Без него выполнение не останавливается на следующей метке, а идёт дальше — в код соседних веток. Это называют «проваливанием» (fallthrough).

C++
int mark = 4;

switch (mark) {
    case 5:
        std::cout << "Отлично\n";
    case 4:
        std::cout << "Хорошо\n";
    case 3:
        std::cout << "Удовлетворительно\n";
}

Программа напечатает две строки: «Хорошо» и «Удовлетворительно». Метка case 4 — это только точка входа, а не отдельный блок. Забытый break — самая частая ошибка при работе со switch.

Если проваливание задумано, скажите об этом явно атрибутом [[fallthrough]] — предупреждение исчезнет, а читателю кода будет понятно, что break пропущен намеренно:

C++
switch (level) {
    case 3:
        unlockBonus();
        [[fallthrough]];
    case 2:
        unlockLevel();
        break;
}

Несколько значений для одной ветки

Метки можно ставить подряд. Так несколько значений обрабатываются одним кодом:

C++
switch (month) {
    case 12:
    case 1:
    case 2:
        std::cout << "Зима\n";
        break;
    case 3:
    case 4:
    case 5:
        std::cout << "Весна\n";
        break;
    default:
        std::cout << "Лето или осень\n";
}

Здесь проваливание работает на Вас: между метками нет кода, поэтому атрибут [[fallthrough]] не нужен.

Ветка default

default выполняется, когда ни одна метка не подошла. Ветку можно не писать, но лучше оставить: в ней удобно сообщить о неожиданном значении.

C++
switch (command) {
    case 'q':
        quit();
        break;
    default:
        std::cout << "Неизвестная команда\n";
}

default принято ставить последним, хотя язык разрешает любое место.

Что можно проверять в switch

Выражение в скобках должно быть целого типа или перечислением: int, char, long long, bool, enum. После каждой метки case должна стоять константа, известная во время компиляции.

МожноНельзя
case 3:case x:, если x — обычная переменная
case 'a':case "строка":
case Color::red:case 2.5:
case 2 + 3:две одинаковые метки в одном switch

Строки std::string и дробные числа в switch проверить нельзя — для них остаётся if ... else if. Диапазон вроде «от 1 до 10» одной меткой тоже не записать.

Переменные внутри case

Объявить переменную с инициализацией прямо после метки не получится: компилятор сообщит, что переход к следующей метке «перепрыгивает» через инициализацию.

C++
switch (shape) {
    case 1:
        double radius = 2.0;   // ошибка компиляции, если ниже есть другие метки
        std::cout << 3.14159 * radius * radius << '\n';
        break;
    case 2:
        std::cout << "Квадрат\n";
        break;
}

Заключите код ветки в фигурные скобки — у переменной появится своя область видимости:

C++
switch (shape) {
    case 1: {
        double radius = 2.0;
        std::cout << 3.14159 * radius * radius << '\n';
        break;
    }
    case 2:
        std::cout << "Квадрат\n";
        break;
}

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

Начиная с C++17 в скобках можно объявить переменную, которая нужна только внутри switch:

C++
switch (int code = readCode(); code) {
    case 0:
        std::cout << "Успех\n";
        break;
    default:
        std::cout << "Ошибка " << code << '\n';
}

После закрывающей скобки switch переменной code уже не существует.

switch и перечисления

switch особенно удобен вместе с enum class: значения имеют имена, а компилятор следит, чтобы Вы ничего не забыли.

C++
enum class Light { red, yellow, green };

void show(Light light) {
    switch (light) {
        case Light::red:
            std::cout << "Стойте\n";
            break;
        case Light::yellow:
            std::cout << "Ждите\n";
            break;
        case Light::green:
            std::cout << "Идите\n";
            break;
    }
}

Если убрать одну из веток и не писать default, GCC и Clang с флагом -Wall предупредят: enumeration value 'green' not handled in switch. Это защищает от ошибки, когда в перечисление добавили новое значение, а обработать его забыли.

switch или if-else

СитуацияЧто выбрать
Одна переменная сравнивается с набором константswitch
Значения — имена из enumswitch
Условия с диапазонами: x > 10, x <= 0if ... else if
Сравниваются строки или дробные числаif ... else if
В условиях участвуют разные переменныеif ... else if

Частые ошибки

  • Забыли break. Выполняются лишние ветки. Проверяйте каждую ветку и включайте предупреждения о проваливании.
  • Написали условие в метке. Запись case x > 5: не проверяет диапазон: после case должна стоять константа, и компилятор ответит ошибкой case value is not a constant expression.
  • Объявили переменную без фигурных скобок. Компилятор сообщает, что переход к метке обходит инициализацию: jump bypasses variable initialization.
  • Сравнивают строки. switch работает только с целыми значениями и перечислениями.

Коротко

  • switch выбирает ветку по значению целого выражения или перечисления.
  • Каждую ветку заканчивайте break, иначе выполнение «провалится» дальше.
  • default обрабатывает все значения, для которых нет метки.
  • Для переменных внутри ветки нужны фигурные скобки.
  • Для диапазонов, строк и дробных чисел используйте if ... else if.

Все условные конструкции вместе — if, else if, switch и тернарный оператор — разобраны в уроке Условные конструкции в C++, там же есть задачи с автоматической проверкой.

Использованная литература

  1. switch statement — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/language/switch (дата обращения: 08.10.2026).
  2. ISO/IEC 14882:2024 — Язык программирования C++ [Электронный ресурс]. — URL: https://www.iso.org/standard/83626.html (дата обращения: 08.10.2026).