未初始化的局部变量在C静态默认?



我最近了解了静态变量,它们在各种函数调用之间保留它们的值。然后我写了一些代码来测试它,希望它能完美地工作。但是后来我不小心删除了局部变量声明开头的static关键字,实际问题就出现了。除了在声明过程中没有使用static关键字之外,这两个程序的输出是相似的。

没有任何静态声明的代码:
#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 2
return 0;
}
void up(){
int stvar;
stvar++;
printf("%dn", stvar);
}
静态声明的代码:
#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 2
return 0;
}
void up(){
static int stvar;
stvar++;
printf("%dn", stvar);
}

最后我尝试了这个,通过初始化局部变量:

#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 1
return 0;
}
void up(){
int stvar = 0;
stvar++;
printf("%dn", stvar);
}

这一次,局部变量显示了它的自然行为。我只是想知道如果未初始化的局部变量是静态默认?

不,默认不是static。原则上,初始值可以是任何值。使用该值甚至可能是未定义的行为。实际上,编译器在堆栈上为变量选择一个内存位置,变量的初始值是恰好已经在该内存位置中的值。

由于您没有在第一个up()和第二个up()之间运行任何其他代码,因此实际上您的程序可能会两次选择相同的位置,因此它仍然具有先前的值。如果您在两者之间调用另一个函数,该函数的局部变量将进入up()局部变量先前使用的相同空间,这将覆盖第一个up()的值。

你当然不能依赖它。即使您不调用任何其他函数,编译器也可能"秘密地"添加一个。(出于各种原因)。或者编译器可能决定调整两次调用up之间的堆栈,因此每个调用可能为其局部变量获得不同的堆栈位置。

也不能保证第一个值为0。因为它是恰好在那个内存位置的东西,它可能是前一个函数剩下的东西。main不是第一个被调用的函数;在标准库中有一些函数在调用main之前做了一些设置工作。

使用未初始化的自动变量是危险的。如果没有地址,则为未定义行为。否则,就像您的情况一样,stvar的值将是不确定的。它的值可以是任意的,甚至可以在访问之间改变。

总是初始化局部变量。

请注意,静态存储的变量(全局变量和static)为零如果没有显式初始化,则初始化。

最新更新