C++ switch语句 #

一、switch语句概述 #

switch语句是一种多分支选择语句,根据表达式的值选择执行的分支。

1.1 基本语法 #

cpp
switch (expression) {
    case value1:
        // 语句
        break;
    case value2:
        // 语句
        break;
    default:
        // 默认语句
}

1.2 基本使用 #

cpp
int day = 3;

switch (day) {
    case 1:
        std::cout << "星期一" << std::endl;
        break;
    case 2:
        std::cout << "星期二" << std::endl;
        break;
    case 3:
        std::cout << "星期三" << std::endl;
        break;
    case 4:
        std::cout << "星期四" << std::endl;
        break;
    case 5:
        std::cout << "星期五" << std::endl;
        break;
    case 6:
        std::cout << "星期六" << std::endl;
        break;
    case 7:
        std::cout << "星期日" << std::endl;
        break;
    default:
        std::cout << "无效日期" << std::endl;
}

二、switch语句规则 #

2.1 表达式类型限制 #

switch表达式必须是整数类型或枚举类型:

cpp
// 允许的类型
int i = 1;
char c = 'A';
short s = 1;
long l = 1L;
enum Color { RED, GREEN, BLUE };

// 不允许的类型
// float f = 1.0f;
// double d = 1.0;
// std::string str = "hello";

2.2 case标签 #

  • case标签必须是常量表达式
  • case标签不能重复
  • case标签的类型必须与switch表达式类型兼容
cpp
int x = 2;
const int A = 1;

switch (x) {
    case A:       // 正确:常量
        break;
    case 2:       // 正确:字面量
        break;
    // case x:    // 错误:变量
    // case 1:    // 错误:重复
    default:
        break;
}

三、break语句 #

3.1 break的作用 #

break语句用于跳出switch语句。

cpp
int num = 2;

switch (num) {
    case 1:
        std::cout << "一" << std::endl;
        break;
    case 2:
        std::cout << "二" << std::endl;
        break;  // 跳出switch
    case 3:
        std::cout << "三" << std::endl;
        break;
}
// 输出:二

3.2 省略break的穿透 #

cpp
int num = 2;

switch (num) {
    case 1:
        std::cout << "一" << std::endl;
        // 没有break,继续执行
    case 2:
        std::cout << "二" << std::endl;
        // 没有break,继续执行
    case 3:
        std::cout << "三" << std::endl;
        break;
}
// 输出:二\n三

3.3 利用穿透特性 #

cpp
char grade = 'B';

switch (grade) {
    case 'A':
    case 'B':
    case 'C':
        std::cout << "及格" << std::endl;
        break;
    case 'D':
    case 'F':
        std::cout << "不及格" << std::endl;
        break;
    default:
        std::cout << "无效成绩" << std::endl;
}

3.4 多个case共享代码 #

cpp
int month = 2;

switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        std::cout << "31天" << std::endl;
        break;
    case 4: case 6: case 9: case 11:
        std::cout << "30天" << std::endl;
        break;
    case 2:
        std::cout << "28或29天" << std::endl;
        break;
    default:
        std::cout << "无效月份" << std::endl;
}

四、default分支 #

4.1 default的作用 #

default分支处理所有未被case匹配的情况。

cpp
int num = 100;

switch (num) {
    case 1:
        std::cout << "一" << std::endl;
        break;
    case 2:
        std::cout << "二" << std::endl;
        break;
    default:
        std::cout << "其他数字" << std::endl;
}
// 输出:其他数字

4.2 default位置 #

cpp
// default可以在任意位置
switch (num) {
    default:
        std::cout << "其他" << std::endl;
        break;
    case 1:
        std::cout << "一" << std::endl;
        break;
}

// 通常放在最后
switch (num) {
    case 1:
        std::cout << "一" << std::endl;
        break;
    default:
        std::cout << "其他" << std::endl;
}

4.3 省略default #

cpp
// 如果不需要处理其他情况,可以省略default
switch (num) {
    case 1:
        std::cout << "一" << std::endl;
        break;
    case 2:
        std::cout << "二" << std::endl;
        break;
}
// 如果num不是1或2,什么都不做

五、switch中的变量声明 #

5.1 变量作用域 #

cpp
switch (x) {
    case 1:
        int y = 10;  // 错误:可能跳过初始化
        break;
    case 2:
        // y在这里不可见
        break;
}

5.2 正确的变量声明 #

cpp
switch (x) {
    case 1: {
        int y = 10;  // 在块中声明
        std::cout << y << std::endl;
        break;
    }
    case 2: {
        int y = 20;  // 不同的块
        std::cout << y << std::endl;
        break;
    }
}

5.3 在switch外声明 #

cpp
int y;  // 在switch外声明

switch (x) {
    case 1:
        y = 10;
        break;
    case 2:
        y = 20;
        break;
}

六、switch vs if-else #

6.1 使用switch的场景 #

cpp
// 多个离散值判断
switch (option) {
    case 1: /* ... */ break;
    case 2: /* ... */ break;
    case 3: /* ... */ break;
}

6.2 使用if-else的场景 #

cpp
// 范围判断
if (score >= 90) {
    // ...
} else if (score >= 80) {
    // ...
}

// 复杂条件
if (x > 0 && y > 0) {
    // ...
}

// 浮点数判断
if (x > 0.5) {
    // ...
}

6.3 性能比较 #

cpp
// switch:编译器可能优化为跳转表,效率高
switch (x) {
    case 1: case 2: case 3: /* ... */
}

// if-else:顺序判断
if (x == 1) {
    // ...
} else if (x == 2) {
    // ...
} else if (x == 3) {
    // ...
}

七、C++17 switch初始化 #

7.1 基本语法 #

cpp
switch (init; expression) {
    // ...
}

7.2 使用示例 #

cpp
switch (auto x = getValue(); x) {
    case 1:
        std::cout << "一" << std::endl;
        break;
    case 2:
        std::cout << "二" << std::endl;
        break;
    default:
        std::cout << "其他" << std::endl;
}
// x在这里不可见

八、枚举与switch #

8.1 枚举类型 #

cpp
enum Color { RED, GREEN, BLUE };

Color c = GREEN;

switch (c) {
    case RED:
        std::cout << "红色" << std::endl;
        break;
    case GREEN:
        std::cout << "绿色" << std::endl;
        break;
    case BLUE:
        std::cout << "蓝色" << std::endl;
        break;
}

8.2 枚举类(C++11) #

cpp
enum class Color { RED, GREEN, BLUE };

Color c = Color::GREEN;

switch (c) {
    case Color::RED:
        std::cout << "红色" << std::endl;
        break;
    case Color::GREEN:
        std::cout << "绿色" << std::endl;
        break;
    case Color::BLUE:
        std::cout << "蓝色" << std::endl;
        break;
}

九、实际应用 #

9.1 菜单选择 #

cpp
void showMenu() {
    std::cout << "1. 新建" << std::endl;
    std::cout << "2. 打开" << std::endl;
    std::cout << "3. 保存" << std::endl;
    std::cout << "4. 退出" << std::endl;
}

int main() {
    int choice;
    showMenu();
    std::cin >> choice;
    
    switch (choice) {
        case 1:
            std::cout << "新建文件" << std::endl;
            break;
        case 2:
            std::cout << "打开文件" << std::endl;
            break;
        case 3:
            std::cout << "保存文件" << std::endl;
            break;
        case 4:
            std::cout << "退出程序" << std::endl;
            break;
        default:
            std::cout << "无效选择" << std::endl;
    }
    
    return 0;
}

9.2 计算器 #

cpp
double calculate(double a, double b, char op) {
    switch (op) {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            if (b != 0) return a / b;
            else {
                std::cout << "除数不能为0" << std::endl;
                return 0;
            }
        default:
            std::cout << "无效运算符" << std::endl;
            return 0;
    }
}

9.3 状态机 #

cpp
enum State { IDLE, RUNNING, PAUSED, STOPPED };

State state = IDLE;

void handleEvent(int event) {
    switch (state) {
        case IDLE:
            if (event == 1) state = RUNNING;
            break;
        case RUNNING:
            if (event == 2) state = PAUSED;
            else if (event == 3) state = STOPPED;
            break;
        case PAUSED:
            if (event == 1) state = RUNNING;
            else if (event == 3) state = STOPPED;
            break;
        case STOPPED:
            if (event == 4) state = IDLE;
            break;
    }
}

十、最佳实践 #

10.1 始终添加break #

cpp
// 不推荐:忘记break
switch (x) {
    case 1:
        doSomething();
        // 忘记break!
    case 2:
        doOther();
        break;
}

// 推荐:每个case都有break
switch (x) {
    case 1:
        doSomething();
        break;
    case 2:
        doOther();
        break;
}

10.2 添加default分支 #

cpp
// 推荐:总是添加default
switch (x) {
    case 1:
        // ...
        break;
    default:
        std::cout << "未知选项" << std::endl;
}

10.3 使用枚举代替魔法数字 #

cpp
// 不推荐
switch (x) {
    case 1: break;
    case 2: break;
}

// 推荐
enum Option { NEW = 1, OPEN = 2, SAVE = 3 };
switch (x) {
    case NEW: break;
    case OPEN: break;
    case SAVE: break;
}

十一、总结 #

switch语句要点 #

要点 说明
表达式类型 整数或枚举
case标签 常量表达式
break 跳出switch
default 默认分支
穿透 没有break继续执行

switch vs if-else #

特性 switch if-else
判断类型 整数/枚举 任意类型
条件形式 离散值 范围/复杂条件
性能 可能更优 顺序判断
可读性 多分支时更好 简单条件更好

下一步,让我们学习循环语句!

最后更新:2026-03-26