【C/C++/Java】switch-case 语句中没有 break 会发生什么?(“击穿”现象)

在日常开发中,switch-case 语句是非常常见的分支控制结构。但很多初学者(甚至有一定经验的开发者,比如我记得我在大一下用 C++ MFC 进行桌面端软件开发时还犯了这个错误)都会踩一个坑:忘记写 break

那么问题来了:
👉 如果 switch-case 中没有 break,程序到底会发生什么?

这篇文章带你彻底搞清楚这个问题。


一、先说结论

C / C++ / Java 中:

如果 case 后没有 break,程序会继续执行后续的 case(此时不再判断后续的 case 是否还满足条件,直到再次碰到 break 语句为止)。

👉 这种现象叫做:“击穿(fall-through)”


二、代码示例

我们来看一个简单例子:

#include <stdio.h>

int main() {
    int x = 2;

    switch (x) {
        case 1:
            printf("One\n");
        case 2:
            printf("Two\n");
        case 3:
            printf("Three\n");
        default:
            printf("Default\n");
    }

    return 0;
}

1. 运行结果:

Two
Three
Default

2. 原因解释

执行流程如下:

  1. x = 2,进入 case 2
  2. 输出:Two
  3. ❗没有 break → 继续往下执行
  4. 执行 case 3 → 输出 Three
  5. 继续执行 default → 输出 Default

👉 注意:后续的 case 不会再判断条件,而是直接顺序执行!

3. 如果再加上 break

如果我们加上 break

switch (x) {
    case 1:
        printf("One\n");
        break;
    case 2:
        printf("Two\n");
        break;
    case 3:
        printf("Three\n");
        break;
    default:
        printf("Default\n");
}

输出:

Two

👉 这才是我们通常期望的行为。

4. C / C++ / Java 三种语言在 switch-case 语句都有 “击穿” 现象

C / C++ / Java 三种语言在 switch-case 语句 “击穿” 现象这一点上完全一致:

语言 是否会发生击穿
C ✅ 支持
C++ ✅ 支持
Java ✅ 支持

从 Java 14 开始,引入了增强版 switch-> 语法,是一种 lambda 表达式,也可以理解为一种匿名函数):

switch (x) {
    case 1 -> System.out.println("One");
    case 2 -> System.out.println("Two");
    case 3 -> System.out.println("Three");
}

👉 特点:

  • 不需要 break
  • 不会发生击穿
  • 安全且简洁

三、什么时候可以不写 break?

虽然大多数情况下需要 break,但有些场景是刻意利用击穿的。
例如下面这种想要把多个条件合并的情况(逻辑为 “或” ):

switch (x) {
    case 1:
    case 2:
    case 3:
        printf("1~3之间\n");
        break;
    default:
        printf("其他\n");
}

👉 作用:

  • 1、2、3 都执行同一逻辑
  • 减少重复代码

当然,在 Java 14 及以后中,上面这种写法也没有必要了,其 switch 语句支持在一个 case 后写多个条件(用逗号分隔),满足任意一个就会执行对应代码块

int day = 3;

switch (x) {
    case 1, 2, 3:
        printf("1~3之间\n");
        break;
    default:
        printf("其他\n");
}

四、常见坑总结

❌ 1. 忘记写 break(最常见)

case 1:
    doSomething();
// 忘了 break
case 2:
    doAnotherThing();

👉 会导致逻辑错误,非常隐蔽!有的试卷上的改错题也会设置类似的 Bug 让你改。

这也是人潜意识里的一种误解:

  • switch-case 语句中的 case 的逻辑并不是:“满足其条件,就选择执行其后面的语句块”(尽管我们学习的过程中很容易得到这样一种理解上的错觉);
  • 而是 “满足其条件,就从这里 ‘进入’ ”(关于“进入”的含义,可以参考 C 语言中的 goto 语句)。
    这也是为什么 switch-case 语句中没有 break 的时候,执行后续的语句时不再判断是否符合 case 后面条件的要求就一路执行下去(直到碰到 break),因为 case 只管从这里 “进入”,不能起到 “拦截” 的作用(这一作用是由 break 来控制的)。

❌ 2. default 也会被击穿执行

很多人以为 default 是“最后才执行”,其实不是:

case 2:
    ...
default:
    ...

👉 如果没有 break,照样会执行到 default。

事实上,switch-case 语句中的 default 语句并不是只能放到最后面写的,只不过放到最后面是人们的习惯(符合人类思维方式及其逻辑)而已。因此如果发生了 “击穿” 现象, default 语句也跟别的 case 语句一样,在遇到 break 之前按照顺序被执行。


五、总结与建议

✔ 每个 case 后默认加 break
✔ 除非你明确需要击穿
✔ 利用 IDE 警告(很多编译器会提示 fall-through)
✔ 在需要击穿时加注释:

case 1:
    printf("One\n");
    // fall through
case 2:
    printf("Two\n");
    break;

总结:

👉 switch-case 没有 break,会导致程序继续执行后续 case(此时不再判断后续的 case 是否还满足条件,直到再次碰到 break 语句为止),这种现象被称为 “击穿” 现象


六、思考题

下面的代码会输出什么?

int x = 1;

switch (x) {
    case 1:
        printf("求");
    case 2:
        printf("关");
    case 3:
        printf("注");
}

👉 欢迎在评论区写出你的答案 👇

如果这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 🔔!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐