切换案例奇怪的范围
回顾一些第三方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的情况下中断,则答案还可以包括行为。
它不仅有效,在实际代码中也使用了类似的结构,例如Duff的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
语句实际上只是计算一个地址并跳转到它,因此很容易看出为什么它可以与其他控制结构重叠; 其他控制结构中的行也有跳转目标的地址!
在您提供的情况下,想象您的代码中是否没有switch
或break
。 当你完成执行if
语句的then
一部分时,你就继续前进,所以你会陷入case 2:
. 现在,既然你有switch
和break
,重要的是break
可以突破。 根据MSDN页面,“The C break statement” ,
break语句终止执行它出现的最近的封闭do , for , switch或while语句。 控制传递给终止语句后面的语句。
由于最近的封闭do , for , switch或while语句是您的开关 (请注意, 如果未包含在该列表中),那么如果您在then
块内, then
转移到switch
语句的外部。 但是,更有趣的是,如果输入case 0
会发生什么,但是c == 'A'
是假的。 然后, if
将控制转移到then
块的右括号then
,并开始执行case 2
的代码。
在C和C ++中,只要不跳过任何变量声明,就跳入循环和if块是合法的。 您可以使用goto
查看此答案以获取示例,但我不明白为什么相同的想法不适用于switch
块。
语义不同于如果}
高于case 1
正如您所期望的那样。
这段代码实际上说如果state == 0
和c != 'A'
那么转到case 2
因为那是if
语句的右括号。 然后它处理该代码并在case 2
代码的末尾命中break
语句。