在switch语句中使用continue

Mat*_*ner 74 c c++ continue break switch-statement

我想从switch语句的中间跳转到以下代码中的循环语句:

while (something = get_something())
{
    switch (something)
    {
    case A:
    case B:
        break;
    default:
        // get another something and try again
        continue;
    }
    // do something for a handled something
    do_something();
}
Run Code Online (Sandbox Code Playgroud)

这是一种有效的使用方式continue吗?continue语句是否忽略了switch语句?C和C++在这方面的行为有何不同?

vis*_*tor 51

没关系,continue语句与封闭循环有关,你的代码应该等同于(避免这样的跳转语句):

while (something = get_something()) {
    if (something == A || something == B)
        do_something();
}
Run Code Online (Sandbox Code Playgroud)

但是如果你希望break退出循环,就像你的评论所暗示的那样(它总是再次尝试另一个东西,直到它的计算结果为false),你需要一个不同的结构.

例如:

do {
    something = get_something();
} while (!(something == A || something == B));
do_something();
Run Code Online (Sandbox Code Playgroud)

  • 仅在语义意义上的“等效”。编译器生成的代码非常不同。使用 switch 语句,编译器可以生成一个跳转表,避免多次比较,因此比对每个元素 1 乘 1 进行比较要快得多。 (2认同)
  • @avakar switch 语句要求 case 为常量值,因为 if 语句不是这种情况,它不能进行相同的优化(注意:我说的是一般情况,给定某些要求是可能的(例如仅 const 值) ,仅某些逻辑运算符等)来进行优化,但它高度依赖于编译器并且YMMV)。 (2认同)

小智 20

是的,没关系 - 就像在if声明中使用它一样.当然,你不能使用a break来打开交换机内部的循环.

  • 哇对不起,我在 PHP 中看到了这个,以为这是一个老做法,结果它只是 PHP ...... (2认同)

小智 10

是的,switch语句将忽略continue,并将进入要测试的循环的条件.我想与Ritchie的C编程语言参考文献分享这个摘录:

continue陈述与[ break但较少使用]相关; 它会导致封闭的下一次迭代for,whiledo循环开始.在while和中do,这意味着测试部分立即执行; 在for,控制传递到增量步骤.

continue语句仅适用于循环,而不适用于switch语句.一个continue内部的switch一个循环内导致下一个循环迭代.

我对C++不太确定.


SF.*_*SF. 7

它在语法上是正确的,风格上还可以.

好的风格要求每个case:语句都应该以下列之一结束:

 break;
 continue;
 return (x);
 exit (x);
 throw (x);
 //fallthrough
Run Code Online (Sandbox Code Playgroud)

此外,case (x):紧接着

 case (y):
 default:
Run Code Online (Sandbox Code Playgroud)

是允许的 - 捆绑几个具有完全相同效果的案例.

还有什么怀疑是错误的,就像if(a=4){...} 你当然需要封闭环路(while,for,do...while)的continue工作.它不会case()独自循环回来.但是构造如下:

while(record = getNewRecord())
{
    switch(record.type)
    {
        case RECORD_TYPE_...;
            ...
        break;
        default: //unknown type
            continue; //skip processing this record altogether.
    }
    //...more processing...
}
Run Code Online (Sandbox Code Playgroud)

...没关系.

  • @SF。好吧,我可以很容易地想象出将“default:”设置为第一个而不是最后一个更有意义的情况。就像“这样做,除非你得到以下异常值,应该按如下方式处理”。 (3认同)
  • 对不起necroposting,但我想补充一点,对`exit`的调用通常也是一个很好的结束切换案例. (2认同)

Ale*_*tov 5

尽管从技术上讲是有效的,但所有这些跳跃都模糊了控制流程-尤其是continue声明。

我会把这种技巧作为最后的手段,而不是第一个。

怎么样

while (something = get_something())
{
    switch (something)
    {
    case A:
    case B:
        do_something();
    }        
}
Run Code Online (Sandbox Code Playgroud)

它更短,以更清晰的方式显示其内容。

  • @Matt:那可能意味着更加混乱的结构... :) (2认同)