【问题标题】:Nested case statements within switchswitch 中的嵌套 case 语句
【发布时间】:2017-01-08 13:31:55
【问题描述】:

所以我已经为此苦苦挣扎了一段时间,但我不明白为什么会这样。

int main(void)
{
    int sum = 0;

    for(int i = 0; i < 10; i++) {
        switch(i) {
            case 1: case 4: case 7: sum++;
            default: continue;
            case 5: break;
        }
        break;
    }

    printf("%d", sum);
}

输出:

2

我无法在其他任何地方找到有关嵌套 case 语句的任何信息。

【问题讨论】:

  • “Fallthrough”是要搜索的关键字。 (它们并不是真正的“嵌套”,实际上它们经常被写在下面彼此。)
  • 除此之外:养成breakcase 的习惯。虽然你的continue 意味着你不需要它,但如果你省略它,你最终可能会得到比 case fall-through 更意想不到的东西......循环在 i=1i=4 上递增 sum ,并停在i=5...0+1+1 == 2。如果您不需要条件流,但可以选择需要条件值,则 LUT 更快更简单:sum=0; for(var i = 0; i &lt; 10; i++) sum+={1:1,4:2,7:3}[i]||0;
  • 这是使用符号编译的绝佳机会,在调试器中运行代码以逐行跟踪程序,检查相关变量的值以了解实际情况。

标签: c loops switch-statement


【解决方案1】:
switch(i) {
    case 1: case 4: case 7: sum++;
    default: continue;
    case 5: break;
}

上面可以等价地改写为

switch(i) {
    case 1:
    case 4:
    case 7: sum++;
    default: continue;
    case 5: break;
}

案例14 显示失败。这意味着执行将进入下一个 case 语句。最终导致所有三种情况都执行相同的代码。

需要注意的有趣部分是default 也是一个有效标签。而且它不必最后出现!如果删除continue 语句,则执行将从default 继续执行到case 5,并且当i2 时循环将结束。

【讨论】:

  • 我不知道为什么,但是在其他任何地方都有default: 但最后真的让我毛骨悚然......哈哈。
  • @LudvigRydahl 多年的最后看到它会对你产生影响 :) 虽然当我最初学习 C 时,我经常想知道为什么默认情况不在顶部。
  • 我想是的。好吧,既然您这么说,那么将它放在那里实际上并没有那么奇怪。但是,对我来说,最后使用默认值会更容易阅读,因为我将其视为 "if all failed" 案例,如“它已经经历了所有案例,没有匹配任何案例,所以现在我们在这里”。我想这一切都归结为个人喜好。 :)
【解决方案2】:

它们没有嵌套。它们只是同一 sum++; 指令的三个标签。

i==1i==4 的情况下代码跳转到那里,因此sum 变为2。值 0、2 和 3 导致 switch 跳转执行 default 标签,这是一条 continue; 指令,导致循环进行下一次迭代。

i==5 上,切换以内部break; 指令终止,并继续执行switch(i){...} 之后的break。这会导致循环终止,因此i 变量永远不会达到值 7,而sum 保持为 2。

【讨论】:

    最近更新 更多