为什么全局变量总是初始化为'0',而不是局部变量?

yuv*_*esh 52 c variables global local

可能重复:
为什么全局变量和静态变量初始化为默认值?

看代码,

#include <stdio.h>

int a;
int main(void)
{
    int i;
    printf("%d %d\n", a, i);
}
Run Code Online (Sandbox Code Playgroud)

产量

0 8683508
Run Code Online (Sandbox Code Playgroud)

这里'a'用'0'初始化,但'i'用'垃圾值'初始化.为什么?

K-b*_*llo 110

因为这是它的方式,根据C标准.原因是效率:

  • 静态变量在编译时初始化,因为它们的地址是已知的并且是固定的.将它们初始化为0不会产生运行时成本.

  • 自动变量可以针对不同的调用具有不同的地址,并且每次调用函数都必须在运行时初始化,从而产生可能不需要的运行时成本.如果确实需要初始化,请提出请求.

  • 实际上静态变量也在运行时初始化.C运行时(crt)将在调用main之前初始化它们.当然,这只发生一次,但仍然在运行时. (14认同)
  • 此外,您无法在编译时初始化任何内容.程序需要启动并加载到内存中,以便您可以删除内容(在本例中为bss部分).在编译时不可能只运行时.干杯 (9认同)
  • 如果全局变量未初始化为非零值,则在"main"程序启动之前,在加载过程映像时将它们设置为零.这是一次性操作,与"每次调用函数"操作本地变量相比. (5认同)

Rag*_*ddy 41

globalstatic当初始化时,变量存储在数据段(DS)中,当未初始化时,变量存储在符号(BSS)的块中.

这些变量具有固定的内存位置,并且在编译时分配内存.

因此global,static变量具有'0'默认值.

auto变量存储在堆栈上,而他们没有一个固定的内存位置.

内存auto在运行时分配给变量,但不在编译时分配.因此auto变量的默认值为垃圾.

  • 这不完全正确..bss在编译期间没有分配,实际上这是将.bss作为未初始化/零静态/全局变量的特殊部分引入的原因.只需要存储大小信息,因此二进制文件不会被不必要的数据(即零)破坏.在运行时,.bss变量初始化为零(与.data部分中的变量不同,其中实际初始值_has_存储在二进制文件中).除此之外,我认为这是更好的答案,+ 1 :-) (5认同)

Jon*_*ler 16

您选择了简单变量,但请考虑:

void matrix_manipulation(void)
{
    int matrix1[100][100];
    int matrix2[100][100];
    int matrix3[100][100];

    /* code to read values for matrix1 from a file */
    /* code to read values for matrix2 from a file */
    /* code to multiply matrix1 by matrix2 storing the result in matrix3 */
    /* code to use matrix3 somehow */
}
Run Code Online (Sandbox Code Playgroud)

如果系统将数组初始化为0,则会浪费工作量; 初始化被函数的其余部分覆盖.C尽可能避免隐藏成本.

  • @ K-ballo:是的,您是对的,但是当变量是较大的数组,结构或结构数组时,代价会更明显。即使初始化了几十个整数变量也不是很引人注意,但是数千个整数值却变得引人注目。 (2认同)

WiS*_*GaN 7

main函数启动之前分配和初始化全局变量,而在程序实例运行时在堆栈上生成局部变量.