C++ 为什么在另一个案例的块中允许case语句?
我遇到过如下代码:C++ 为什么在另一个案例的块中允许case语句?,c++,switch-statement,C++,Switch Statement,我遇到过如下代码: switch(i) { case 2: { std::cout << "2"; break; case 3: std::cout << "3"; break; } case 4: { std::cout << "4"; break; } } 开关(一){ 案例2:{ C/C++中的std::coutswitch语
switch(i) {
case 2: {
std::cout << "2";
break;
case 3:
std::cout << "3";
break;
}
case 4: {
std::cout << "4";
break;
}
}
开关(一){
案例2:{
C/C++中的std::coutswitch
语句是一种美化的goto
语句(具有一些优化优势)
因此,您可以使用case
标签,就像使用goto
标签一样。特别是,只要您不绕过任何变量初始化,就可以在块内跳转。您可以但不应该在开关中滥用case标签
比这更糟糕,也比.Duff's d更糟糕evice有着令人怀疑的特权,几乎似乎有用,但却可以被视为滥用开关
<> P>不是所有的滥用代码>开关可以声称是有用的。例如,这编译为C或C++,即使有严格的警告设置:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
unsigned seed;
if (argc == 2)
seed = atoi(argv[1]);
else
seed = time(0);
printf("seed: %u\n", seed);
srand(seed);
int i = rand() % 10;
int j = 21;
int k = 37;
printf("i: %d\n", i);
switch (i)
{
case 1:
for (j = 10; j > i; j--)
{
case 2:
printf("case 2:\n");
for (k = j - 1; k > 0; k--)
{
case 6:
printf("case 6:\n");
default:
printf("%d-%d-%d\n", i, j, k);
}
case 5:
printf("case 5:\n");
printf("%d-%d\n", i, j);
break;
}
break;
case 3:
printf("case 3:\n");
break;
}
return 0;
}
#包括
#包括
#包括
int main(int argc,字符**argv)
{
无标记种子;
如果(argc==2)
seed=atoi(argv[1]);
其他的
种子=时间(0);
printf(“种子:%u\n”,种子);
srand(种子);
int i=rand()%10;
int j=21;
int k=37;
printf(“i:%d\n”,i);
开关(一)
{
案例1:
对于(j=10;j>i;j--)
{
案例2:
printf(“案例2:\n”);
对于(k=j-1;k>0;k--)
{
案例6:
printf(“案例6:\n”);
违约:
printf(“%d-%d-%d\n”,i,j,k);
}
案例5:
printf(“案例5:\n”);
printf(“%d-%d\n”,i,j);
打破
}
打破
案例3:
printf(“案例3:\n”);
打破
}
返回0;
}
参数处理允许您设置种子,以便您可以根据需要复制结果。我不认为它有用;事实上,它没有用处。请注意,循环内部的break
会中断循环,而不是开关
基本上,大小写
标签(和默认值
)必须在开关
的范围内,并且与最里面的开关
相关联。它们几乎没有其他约束。必须小心不要跳过变量初始化等(这就是为什么j
和k
是在开关()之外定义的。)但是,否则,它们只是标签,控件将在适当的时候流向它们。>代码>开关> /Cuth>在C和C++中的语句并不像您所想的那样逻辑。请参阅极端例子。@ NeilButterworth,这是一个深远的声明,我不能同意。@ NeilButterworth,当使用合理时,提供良好的阅读。能力(与一长串的if…else if…
语句相比)在某些情况下提供了优化的好处。前者的好处大于后者。@NeilButterworth实际上,没有“魔力”相信开关
块平均生成更快的代码,只是简单的逻辑。开关
块执行一次检查和一次或两次跳转(跳转到案例
,在中断时跳出
(如果存在)),而未优化的if..else if..else
链执行一次检查和跳转(到else
,或到链的末端)每执行if
(这意味着对于if..else if..else if..else
块,它执行1-3次检查和跳转)。对于任何可以写为其中一个的块,开关
平均效率会稍高一些。开关块强烈提示优化编译器应该将其优化为跳转表。一系列if语句强烈提示它不应该。我见过编译器将转换一系列If语句转换为跳转表,@Justin,但绝大多数情况下,它不会。假设您将写出您的意思。如果一系列If语句的大小写超过可读范围,则您将其作为开关大小写,并应将其编译为跳转表。否则,跳转表的开销为每性能损失。