C语言中的变量定义忽略
代码: 输出: 它为b打印一些垃圾值 b的声明什么时候在这里发生C语言中的变量定义忽略,c,variables,C,Variables,代码: 输出: 它为b打印一些垃圾值 b的声明什么时候在这里发生 为什么b在这里没有初始化为20 开关直接跳转到案例1:,从不执行赋值。因为内存将分配给int b,但当应用程序运行时,b=20将永远不会被计算 这是因为您的开关-语句将跳转到案例1:1或默认值:,跳过有问题的语句-因此b将被取消初始化并调用未定义的行为 以下两个问题(及其公认的答案)将进一步帮助您寻找答案: 2 当您试图编译源代码时,将编译器警告/错误转为更高级别将有望为您提供这些信息 下面是关于此事的gcc说明 int
为什么b在这里没有初始化为20 开关直接跳转到
案例1:
,从不执行赋值。因为内存将分配给int b
,但当应用程序运行时,b=20
将永远不会被计算
这是因为您的开关
-语句将跳转到案例1:
1或默认值:
,跳过有问题的语句-因此b
将被取消初始化并调用未定义的行为
以下两个问题(及其公认的答案)将进一步帮助您寻找答案:
- 2
当您试图编译源代码时,将编译器警告/错误转为更高级别将有望为您提供这些信息 下面是关于此事的
gcc
说明
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;
}
1由于
int a
将始终为1(一),因此它将始终在此处跳转
两个链接中最相关的两个,由我回答。大概是因为
开关的功能类似于转到-如果a==1
,它会直接跳到案例1:
,并绕过b
的初始化
也就是说:我知道switch
直接跳转到case
标签,但我很惊讶编译器没有抱怨初始化失败。因为那一行永远也达不到。当C点击一个开关(a)
语句时,它会分支到与您要打开的变量的条件相匹配的案例。初始化b
的语句不在任何情况下。我假设编译器可以自由地将20
写入该位置,但该语言不要求它这样做,在这种情况下它也不要求这样做:它也可以自由地保留初始化,直到它实际执行赋值。Switch语句只计算其中的部分代码,你不能把代码放在最上面,然后期望每个案例组件都对它进行评估。您需要在程序中把b初始化放在switch语句上方的较高位置。如果您确实需要在本地执行此操作,请在一组单独的大括号中执行此操作:
代码:
在switch语句下和case语句外初始化B是一个非常糟糕的主意。要理解这里发生了什么,您必须知道开关跳转到正确的case/default语句。因为当开关(a)语句执行时,控制直接转到语句case 1:不执行语句int b=20,这就是为什么它给出垃圾值作为答案。如果要打印a,则必须在案例1:block中初始化,或者必须在switch(a)语句之前初始化 @0A0D这不是那个问题的重复。初始化位于开关的另一部分(在案例中),投票结果最靠前的答案不适用于此处。@0A0D:不,它不是该问题的副本。答案是,在case标签后面加上变量声明是一个语法错误。而这是因为开关导致跳过初始化器代码。@PaulP.R.O.:请参见问题中的答案:@0A0D在上下文中仍然不如下面refp的答案好。我认为这个问题应该继续存在。@P.R.O:质量是另一个问题。
foo.cpp:6:10: error: jump to case label [-fpermissive]
foo.cpp:5:9: error: crosses initialization of 'int 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;
}