切换案例奇怪的范围

时间:2013-06-19 13:16:07

标签: c syntax switch-statement duffs-device

回顾一些第三方C代码,我遇到了类似的内容:

switch (state) {
case 0: 
    if (c=='A') { // open brace
        // code...
    break; // brace not closed!
case 1:
    // code...
    break;
    } // close brace!
case 2:
    // code...
    break;
}

在我正在审查的代码中,这似乎只是一个错字,但我很惊讶它编译时没有错误。

为什么这是有效的C?
与在预期位置关闭支撑相比,对此代码执行的影响是什么? 有什么情况可以使用吗?

编辑:在示例中,我查看了所有中断(如上所述) - 但如果在0或1的情况下中断,则答案也可能包括行为。

2 个答案:

答案 0 :(得分:12)

它不仅有效,在实际代码中使用了类似的结构,例如Duff's Device,这是一个用于复制缓冲区的展开循环:

send(to, from, count)
register short *to, *from;
register count;
{
        register n = (count + 7) / 8;
        switch(count % 8) {
        case 0: do {    *to = *from++;
        case 7:         *to = *from++;
        case 6:         *to = *from++;
        case 5:         *to = *from++;
        case 4:         *to = *from++;
        case 3:         *to = *from++;
        case 2:         *to = *from++;
        case 1:         *to = *from++;
                } while(--n > 0);
        }
}

由于switch语句实际上只是计算地址并跳转到它,因此很容易理解为什么它可以与其他控制结构重叠;其他控制结构中的行也有跳转目标的地址!

在您提交的案例中,假设您的代码中没有switchbreak。当您完成执行then语句的if部分后,您就继续前进,这样您就可以进入case 2:。现在,由于您拥有switchbreak,因此break可以突破的重要性。根据{{​​3}},

  

中断语句终止执行最近的封闭执行执行切换 while 语句出现。控制传递给终止语句后面的语句。

由于最近的执行 切换语句是您的切换(请注意如果未包含在该列表中),那么如果您在then块内,则转移到switch语句的外部。但是,如果您输入case 0c == 'A'为假,会发生什么更有趣的事情。然后if将控件转移到then块的右括号之后,然后开始执行case 2中的代码。

答案 1 :(得分:3)

在C和C ++中,只要不跳过任何变量声明,就跳入循环和if块是合法的。您可以使用goto检查this answer示例,但我不明白为什么相同的想法不适用于switch块。

语义与}高于case 1时的语义不同。
这段代码实际上是说state == 0c != 'A'然后转到case 2,因为那是if语句的右括号。然后它处理该代码并点击break代码末尾的case 2语句。