我遇到了类似这样的代码:
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 ++中运行得很好,如果我是3,则输出3。我来自java背景,所以我对c ++中逻辑块的理解可能缺乏。所以我的问题是:这是故意的行为吗?
答案 0 :(得分:9)
您可以(但不应该)滥用案例标签switch
远比这更糟糕 - 而且远比Duff's Device差。 Duff的设备具有几乎可能有用的可疑特权,但可被视为滥用switch
。
并非所有switch
的滥用行为都声称有用。例如,即使设置了严格的警告,它也会编译成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;
}
参数处理允许您设置种子,因此您可以根据需要重现结果。我没有声称它有用;实际上,它没用。请注意,循环内的break
会破坏循环,而不是switch
。
基本上,case
标签(和default
)必须在switch
的范围内,并且与最内层的switch
相关联。它们几乎没有其他限制。您必须小心不要跳过变量初始化等(这就是j
和k
在switch()
之外定义的原因。但除此之外,它们只是标签,当“适当”时控制将流向它们。
答案 1 :(得分:6)
switch
语句是一个美化的goto
语句(具有一些优化优势)。
因此,您可以使用case
标签与goto
标签一样多。特别是,只要您没有绕过任何变量初始化,就允许在块内跳转。