【发布时间】:2017-02-07 07:04:02
【问题描述】:
我遇到过如下代码:
switch(i) {
case 2: {
std::cout << "2";
break;
case 3:
std::cout << "3";
break;
}
case 4: {
std::cout << "4";
break;
}
}
请注意case 2 打开一个带有花括号的块,该块仅在case 3 之后关闭。起初,这似乎是一个错字,会导致编译器错误,或者更糟糕的是,忽略case 3。但它在 c++ 中工作得很好,如果 i 为 3,则输出 3。我来自 java 背景,所以我可能缺乏对 c++ 中逻辑块的理解。所以我的问题是:这是故意的行为吗?
【问题讨论】:
-
C 和 C++ 中的
switch语句并不像您想象的那样逻辑。请参阅Duff's device 获取极端示例。 -
@NeilButterworth,这是一个影响深远的声明,我不能同意。
-
@NeilButterworth,开关在合理使用时提供良好的可读性(与
if...else if...语句的长列表相比),并且在某些情况下提供优化好处。前者的好处大于后者。 -
@NeilButterworth 实际上,相信
switch块平均可以更快地编写代码并没有什么“魔法”,只是简单的逻辑。switch块进行一次检查和一两次跳转(跳转到case,在break处跳出(如果存在)),而未优化的if..else if..else链进行一次检查和跳转(或者到else,或到链的末尾)每个if执行(这意味着对于if..else if..else if..else块,它会进行 1-3 次检查和跳转)。对于任何可以写成任何一个的块,switch因此平均效率会稍微高一些。 -
switch 块是对优化编译器的强烈提示,它应该将其优化为跳转表。一系列 if 语句强烈暗示它不应该这样做。我见过编译器会将一系列 if 语句转换为跳转表的情况,@Justin,但绝大多数情况下,它不会。假设是你会写你的意思。如果情况多于一系列 if 语句的可读性,那么您将其编写为 switch-case,并且应将其编译为跳转表。否则,跳转表的开销就是性能损失。
标签: c++ switch-statement