switch case do while 嵌套

4
#include<stdio.h>
int main()
{
    int n=0, i=2;
    switch(1)
    {
    case 0:do
           {
    case 1: n++;
    case 2: n++;
           }while(--i > 0);
    }
    printf("n = %d",n);
}

我原本期望以上代码的输出结果为0,因为case 1和case 2均位于do while语句中,而该语句又嵌套在case 0内。Switch测试值为1,因此永远不会执行case 0,也就是说case 1和case 2也不会执行。

n的值却为4。有何解释吗?


4
Duff的装置是一种用于优化循环的技巧,通过在循环中交错复制和跳转以减少循环迭代次数。这个技巧利用了switch语句的fall-through行为,并且被称作"loop unrolling"的一种形式。它被广泛应用于C语言和汇编语言中,但是在其他高级语言中并不常见。 - mafso
1
@BrianDriscoll 这是不正确的。如果一个 case 语句没有 break,那么执行将会继续下去。 - Code-Apprentice
1
我认为在 do 循环中使用 break 会退出循环,而不是退出 switch - Bathsheba
1
@Bathsheba:是的,break指的是最近的包含switchwhiledofor语句。而continue则指最近的包含whiledofor语句。(可能是IOCCC的素材。) - Keith Thompson
1
可能是Mixed 'switch' and 'while' in C的重复问题。 - midor
显示剩余5条评论
1个回答

7

你的代码跳到了循环的中间。从那个点开始,它会忽略switch语句的情况,所以它会执行n++n++、检查条件、循环等操作。如果你把case看作是一个标签,switch看作是一个goto,会更容易理解:

    int n=0, i=2;

    if (1 == 0)
        goto label0;
    else if (1 == 1)
        goto label1;
    else if (1 == 2)
        goto label2;

label0:
    do {
        puts("loop");
label1:
        n++;
label2:
        n++;
    } while (--i > 0);

与您的原始代码一样,这只是跳过了标签为label1(即puts)的循环体部分,然后继续像正常进入循环一样执行。


@larsmans:根据您的解释,case是标签 - 如果嵌套的switch中外部和内部switch具有相同的case语句,是否会导致问题。例如,如果我在case 0中放置以下内容: switch(i) { case 1:printf(“here1”); case 2:printf(“here2”); } 现在label1和label2应该冲突,因为它们具有函数作用域。请详细说明。FYI-尽管我做了上述操作,但我没有收到任何错误。 - Sagrian
1
@Sagrian:case ...:标签与最近的封闭switch语句相关联。没有歧义。 - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接