局部变量在C中初始化为零

我认为C中的局部变量没有初始化。 但是当我用gcc编译这段代码时。

void f() { static int s; int n; printf("static s = %d\n", s++); printf("local n = %d\n", n++); f(); } main() { f(); } 

并运行此代码,部分结果是:

 static s = 0 local n = 0 static s = 1 local n = 0 static s = 2 local n = 0 static s = 3 local n = 0 static s = 4 local n = 0 static s = 5 local n = 0 ... static s = 261974 local n = 0 static s = 261975 local n = 0 static s = 261976 local n = 0 static s = 261977 local n = 0 static s = 261978 local n = 0 static s = 261979 local n = 0 static s = 261980 local n = 0 static s = 261981 local n = 0 Segmentation fault: 11 

有人可以解释一下吗? 或者参考C不会初始化本地变量的标准参考?

ISO / IEC 9899:TC3 WG14 / N1256 (C99标准)第6.7.8条第10款:

如果未显式初始化具有自动存储持续时间的对象,则其值不确定。

如果未显式初始化具有静态存储持续时间的对象,则:

  • 如果它有指针类型,则将其初始化为空指针;
  • 如果它有算术类型,则初始化为(正或无符号)零;
  • 如果是聚合,则根据这些规则初始化(递归)每个成员;
  • 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员。

您的变量适合第一类。 不确定意味着它可以是任何东西(包括0)。 仅仅因为它在您执行的测试中为零,并不意味着它总是或者您可以依赖于该行为。 即使使用相同的编译器,行为也可能会发生变化,具体取决于编译选项和优化级别。

根据我的经验,它可能会也可能不会被初始化为0,具体取决于编译器和编译期间使用的标志。

  • 是否有一个gcc标志来初始化本地变量存储?
  • gcc会自动将静态变量初始化为零吗?

本地非static变量未初始化 – 这通常意味着它们包含垃圾。

0与任何其他垃圾值一样有效。 但初始值可能很容易就是42-12345

只是不要这样做。 除非已初始化,否则您需要确保不读取任何变量的值。 读取未初始化的变量具有未定义的行为,这意味着可能的行为不限于打印某些任意值。

这样做的一个好方法是使用显式初始化器:

 int n = 0; 

(顺便提一下,你缺少必需的#include ,而main的正确声明是int main(void) 。)

您正在撰写的内容展示了未定义的行为(我假设您从编译器中获得了责任)。 今天这个编译器使用此输出生成程序的事实并不特别重要。 编译器可能只是将所有堆栈内存设置为零。 或者堆栈可能正在通过先前的归零内存前进。 或者堆栈完全停留在原处(编译器无法“展开”你的主程序,毕竟) n的位置恰好是一个零字。 今天。

如果变量在函数内初始化,则不会自动初始化。 当它在任何函数之外声明时,它被初始化为0。

变量必须具有SOME值; 该语言的规范并不能保证该值是什么。

当您声明一个局部变量时,就像您正在请求内存空间(在这种情况下,在堆栈中)来保存一个值。 由于它是一个内存空间,它总是有一个值。 该值可能由其他线程,程序,系统或先前的函数等设置。实际上,这些值通常被视为垃圾邮件,因为您没有设置它并且其值是随机的。

在您的代码中,f()是递归的,输出显示堆栈的值,直到您运行堆栈内存(堆栈溢出)。