我检查过自己,我写了一个这样的程序
int main() {
int i;
cout << i;
return 0;
}
我运行了该程序几次,结果始终相同,为零。 我用C试过了,结果是一样的。
但是我的教科书说
如果没有初始化已定义的变量 在函数内部,变量值保持未定义。这意味着该元素采用 先前驻留在内存中该位置的任何值。
当程序总是为变量分配空闲内存位置时,这怎么可能?它怎么可能是零以外的值(我假设默认可用内存值为零)?
当程序总是分配空闲内存时,这怎么可能 变量的位置?它怎么可能是某个东西而不是零呢?
让我们看一个实际实现的示例。
假设它利用堆栈来保存局部变量。
void
foo(void)
{
int foo_var = 42;
}
void
bar(void)
{
int bar_var;
printf("%d\n", bar_var);
}
int
main(void)
{
bar();
foo();
bar();
}
上面完全损坏的代码说明了这一点。在我们调用 foo 后,堆栈上放置 foo_var 的特定位置被设置为 42。当我们调用 bar 时,bar_var 占据该确切位置。事实上,执行代码会打印 0 和 42,这表明除非初始化,否则不能依赖 bar_var 值。
现在应该清楚需要局部变量初始化了。但是 main 会是一个例外吗?有没有什么可以与堆栈一起使用并最终给我们一个非零值?
是的。 main 不是程序中执行的第一个函数。事实上,设置一切都需要大量的工作。任何这项工作都可以使用堆栈并在其上留下一些非零值。您不仅不能期望在不同的操作系统上具有相同的值,而且在您现在使用的系统上它很可能会突然发生变化。有兴趣的可以google一下“动态链接器”。 最后,C语言标准甚至没有堆栈这个术语。为局部变量留出一个“位置”是留给编译器的。它甚至可以从给定寄存器中发生的任何事情中获得随机的垃圾。它真的可以是“任何东西”。事实上,如果触发了未定义的行为,编译器可以自由地做任何想做的事情。
如果不初始化函数内定义的变量,则变量值将保持未定义状态。
这句话是真的。这意味着该元素采用先前驻留在内存中该位置的任何值。
这一点不是。获得零有时在实践中会发生这种情况,您应该意识到,对于任何给定的程序运行,
或
未获得零完全符合这一理论。 理论上,如果需要,您的编译器实际上可以为该整数分配一个随机初始值,因此尝试合理化这一点是完全没有意义的。但让我们继续假设“该元素采用先前驻留在内存中该位置的任何值”......
它怎么可能不是零(我假设默认可用内存值为零)?
嗯,这就是当你假设时会发生的情况。 :)
此代码调用
未定义行为非静态变量或
auto变量,即局部变量是不确定
(不确定通常意味着它可以做任何事情。它可以是零,它可以是那里的值,它可以使程序崩溃) 。在赋值之前读取它们会导致未定义的行为。
void myfunc2(){
int x; // value of x is assigned by compiler it can even be 0
printf("%d", x);}
这主要取决于编译器,但一般情况下,编译器会将该值预先假定为 0