代码:
#include <stdio.h>
int var = 20;
int main()
{
int var = var;
printf("%d\n", var);
return 0;
}
GCC在此代码中输出垃圾值。我的疑问是,这应输出“20”。
说明: 每当我们为任何全局/局部变量赋值时,第一条指令是计算机将指定的值保存到寄存器中,然后将其放入内存中。所以,据我所知,当编译器来到“int var = var”时,它应该首先将值20保存到特定寄存器。之后它会将它保存到局部变量。然后全局变量应该超出范围。 是的,它与首先分配变量名称而不是其值的陈述相矛盾。因此,int var使全局var变量超出范围并使局部变量自己赋值,这相当于未初始化的局部变量。
答案 0 :(得分:6)
int var = var;
是未定义的行为。它是具有未初始化值的自我赋值。
答案 1 :(得分:6)
在C和C ++中,变量的范围在声明后立即开始。因此,在读取var
的值以将其分配给var
时,本地var
已在范围内。
讨论寄存器和记忆以及其中的一些东西; C是一种标准化语言,其行为取决于标准。
答案 2 :(得分:2)
int var = var
第二个&#34; var&#34;没有引用全局变量,因此var是未初始化的变量,所以它的值是垃圾
答案 3 :(得分:2)
在C ++中有术语声明点。虽然在C中没有使用这样的术语,但是在C ++和C中,定义标识符声明点的规则实际上是相同的。
我将引用C ++标准中对C有效的引号。
因此
1名称的声明点紧随其后 完整的声明者
所以在声明中的例子中
int var = var;
声明左侧的声明符var隐藏了具有相同名称的全局变量。结果变量var由其自身初始化并具有不确定的值。
C ++标准的另一个例子
2 [注意:直到该点,外部范围的名称仍然可见 隐藏它的名称的声明。[例如:
const int i = 2;
{ int i[i]; }
声明一个包含两个整数的块范围数组。 - 末端示例] - 结束说明 ]
对于枚举
5普查员的声明点紧随其后 枚举器定义。[例如:
const int x = 12;
{ enum { x = x }; }
这里,枚举器x用常量的值初始化 x,即12.-末端示例]
答案 4 :(得分:1)
首先var
是一个全局变量。它的是初始化的。第二个是本地的。刚刚宣布,和编译器认为,=var
正试图将某些东西(没有值,只是垃圾)分配给 local 变量
全局变量被本地变量覆盖。
答案 5 :(得分:1)
编译器在最近的范围(本地)中找到var
而不是全局var
的范围。
您将局部变量的值分配给它自己,并且它是未初始化的。