代码:
int main()
{
int a=1;
switch(a)
{
int b=20;
case 1:
printf("b is %d\n",b);
break;
default:
printf("b is %d\n",b);
break;
}
return 0;
}
输出: 它为b打印一些垃圾值 什么时候b的声明发生在这里 为什么b没有用20初始化?
答案 0 :(得分:8)
因为将为int b
分配内存,但在运行应用程序时,“b = 20
”永远不会被评估。
这是因为您的switch
语句将跳转到case 1:
1 或default:
,跳过相关语句 - 因此{{1}将被取消初始化并调用未定义的行为。
以下两个问题(以及他们接受的答案)将进一步帮助您寻找答案:
How can a variable be used when it's definition is bypassed? 2
<强> Why can't variables be declared in a switch statement? 强>
将编译器警告/错误提升到更高级别时,希望在尝试编译源代码时为您提供此信息。
以下是b
关于此事的说法;
gcc
1 因为foo.cpp:6:10: error: jump to case label [-fpermissive]
foo.cpp:5:9: error: crosses initialization of 'int b'
总是1(一),它总会跳到这里。
2 这两个链接中最相关的,由我回答。
答案 1 :(得分:3)
Switch语句仅评估其中的部分代码,并且您不能将代码置于顶部并期望每个案例组件对其进行评估。您需要在switch语句上方的程序中将b初始化设置得更高。如果你真的需要在本地进行,可以在一组单独的大括号中进行:
代码:
int main()
{
int a=1;
/* other stuff */
{
int b=20;
switch(a)
{
case 1:
printf("b is %d\n",b);
break;
default:
printf("b is %d\n",b);
break;
}
}
/* other stuff... */
return 0;
}
答案 2 :(得分:2)
switch
直接跳转到case 1:
,从不执行任务。
答案 3 :(得分:2)
大概是因为switch
的功能类似于goto
- 如果a == 1
,它会直接跳到case 1:
并绕过b
的初始化。
那就是:我知道switch
直接跳转到case
标签,但我很惊讶编译器没有抱怨错过初始化。
答案 4 :(得分:1)
在switch语句和case语句之外初始化B是一个非常糟糕的主意。要了解这里发生了什么,你必须知道开关跳转到正确的case / default语句。
答案 5 :(得分:1)
因为当switch(a)语句执行时,控制直接转到语句case 1:没有执行语句int b = 20,这就是为什么它给出了垃圾值作为答案的原因。如果你想打印一个,那么你必须在第1种情况下初始化:阻止或你必须在switch(a)语句之前初始化。
答案 6 :(得分:0)
因为永远不会到达那条线。当C命中switch(a)
语句时,它会转移到与您正在启用的变量的条件匹配的case
。初始化b
的语句不属于任何情况。我想编译器可以自由地将20
写入该位置,但是语言并不要求它这样做,并且在这种情况下它不会:它也可以自由地离开初始化直到它实际执行赋值。