第3.9章: switch

English

switch 语句

switch 语句根据表达式的值选择一个分支。 它通常比一长串 if / else if 链更清晰。


switch (expr) {
    case value1:
        stmt1;
        break;
    case value2:
        stmt2;
        break;
    default:
        stmt_default;
        break;
}

每个 case 标签匹配一个常量值。 break 防止执行“贯穿”到下一个 case。

基础示例


::std::int_least32_t x{2};

switch (x) {
    case 1:
        println("one");
        break;
    case 2:
        println("two");
        break;
    default:
        println("other");
        break;
}

贯穿行为

如果某个 case 没有以 break 结尾,执行会继续 (“贯穿”)进入下一个 case。


::std::int_least32_t x{1};

switch (x) {
    case 1:
        println("one");
        // no break here → fallthrough
    case 2:
        println("two");
        break;
}

这会打印:


one
two

贯穿是允许的,但应当有意识地使用。

C++ 属性

C++ 提供了一种标准语法,用于给代码附加额外信息:


[[attribute_name]]

属性不会改变程序的含义,但它们可以给编译器提供 提示,或为读者提升清晰度。

[[fallthrough]] 属性

当你在 switch 中有意允许贯穿时,应当 用 [[fallthrough]] 标记它。 这让意图清晰,并避免编译器警告。


switch (x) {
    case 1:
        println("one");
        [[fallthrough]];   // intentional fallthrough
    case 2:
        println("two");
        break;
}

该属性必须作为一条独立语句出现。

default 分支

当没有其他 case 匹配时,default 标签会执行。


switch (x) {
    case 0:
        println("zero");
        break;
    default:
        println("not zero");
        break;
}

一个分支对应多个 case


switch (x) {
    case 1:
    case 3:
    case 5:
        println("odd small number");
        break;
    default:
        println("other");
        break;
}

嵌套 switch


switch (x) {
    case 1:
        switch (y) {
            case 0:
                println("x=1, y=0");
                break;
            default:
                println("x=1, y!=0");
                break;
        }
        break;
    default:
        println("x!=1");
        break;
}

伪图:switch


          ┌───────────────┐
          │   switch(expr) │
          └───────┬───────┘
                  │
                  ▼
        ┌──────────────────────┐
        │   match a case?       │─── no ───▶ default
        └──────────┬───────────┘
                   │ yes
                   ▼
          ┌───────────────┐
          │   case block   │
          └───────┬───────┘
                  │
                  ├──▶ break ─────────────▶ end
                  │
                  └──▶ fallthrough ───────▶ next case
      

要点