全局变量是否始终在C中初始化为零?

Ale*_*lex 13 c global-variables

#include <stdio.h>
int a[100];
int main(){
    printf("%d",a[5]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码总是打印'0'还是编译器特定的?我正在使用gcc编译器,我输出为'0'.

sim*_*onc 31

是的,所有成员a都保证初始化为0.

从C89标准的3.5.7节

如果没有显式初始化具有静态存储持续时间的对象,则会隐式初始化它,就好像每个具有算术类型的成员都被赋值为0,并且每个具有指针类型的成员都被赋予空指针常量.

  • 啊哈,[C11草案](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)很容易在网上找到.除了[次要更正]之外,草案和最终C11标准之间的差异是装饰性的(http://stackoverflow.com/questions/13914050/what-is-c11-cor-12012/13914051#13914051). (2认同)
  • 1989 C标准与当前标准之间的变化是具有自动存储持续时间的未初始化对象**不具有不确定的值.通常,使用这种对象产生的行为不是由标准定义的. (2认同)
  • 最好的参考将是“最旧的可用参考”,因为它将显示该规则实施了多长时间的历史记录。如果您引用了C18标准,我可能会(错误地)认为这是该标准的新内容。知道1975年编写的C代码会将其全局未初始化变量设置为零是很重要的。我很高兴提及建立该规则的“最旧标准”。 (2认同)

Lun*_*din 9

"全局变量"在文件范围内定义,在任何函数之外.在文件范围定义的所有变量以及使用关键字声明的所有变量都static具有称为静态存储持续时间的变量.这意味着它们将被分配在内存的单独部分中,并在程序的整个生命周期中存在.

这也意味着它们可以保证在任何C编译器上初始化为零.

从目前的C标准C11 6.7.9/10:

"...如果没有显式初始化具有静态或线程存储持续时间的对象,则:

- 如果它有指针类型,则将其初始化为空指针;

- 如果它有算术类型,则初始化为(正或无符号)零;"

实际上,这意味着如果你初始化的全局变量给定值,就会有一个价值,它会在通常被称为内存段分配.data.如果您没有给它一个值,它将被分配在另一个名为的段中.bss.Globals永远不会被分配到堆栈中.


Sam*_*Sam 8

是的。任何全局变量都会初始化为该类型的 默认值。0是默认值并自动转换为任何类型。如果它是一个指针,0则变为NULL

全局变量在数据段中获得被清零的空间。

不是特定于编译器的,而是在 C 标准中定义的。

所以它总是打印0。

  • 此外,我非常怀疑任何现代实现都使用 XOR 来清空内存,因为它会产生额外的读取操作,这是完全没有必要的,并且会增加应用程序的启动时间。异或本身可以很好地清除某些处理器上的寄存器,这些处理器没有“将寄存器设置为零”的特殊指令。将内存区域设置为零并不好。 (3认同)