【问题标题】:Why are global variables always initialized to '0', but not local variables? [duplicate]为什么全局变量总是初始化为'0',而不是局部变量? [复制]
【发布时间】:2012-12-27 05:29:50
【问题描述】:

可能重复:
Why are global and static variables initialized to their default values?

查看代码,

#include <stdio.h>

int a;
int main(void)
{
    int i;
    printf("%d %d\n", a, i);
}

输出

0 8683508

这里 'a' 用 '0' 初始化,但 'i' 用 'junk value' 初始化。为什么?

【问题讨论】:

  • 关闭了,但是最明显的原因没有提到:局部变量只是指向栈的指针,栈一直在变化。

标签: c variables global local


【解决方案1】:

因为它就是这样,根据 C 标准。原因是效率:

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

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

【讨论】:

  • 不错的答案 +1,...全局值在编译时分配 0 na?
  • 如果全局变量未初始化为非零值,则在加载过程映像时,在main 程序启动之前将它们设置为零。与局部变量的“每次调用函数”操作相比,这是一次操作。
  • 实际上静态变量也是在运行时初始化的。 C 运行时 (crt) 将在调用 main 之前初始化它们。当然这只会发生一次,但它仍然在运行时。
  • 另外,你不能在编译时初始化任何东西。该程序需要启动并加载到内存中,以便您可以将内容设为 0(在本例中为 bss 部分)。在编译时是不可能的,只有运行时。欢呼
  • @Sil - 从我检查过的实例来看,您的第一条评论是正确的。但是,你能证明第二个是合理的吗?既然变量分配在加载时就知道了,为什么你认为不可能将初始化值放入二进制图像中,并在图像加载期间设置变量?
【解决方案2】:

globalstatic 变量在初始化时存储在数据段 (DS) 中,在未初始化时存储在数据段 (BSS) 中。

这些变量有一个固定的内存位置,内存是在编译时分配的。

因此globalstatic 变量将'0' 作为它们的默认值。

auto 变量存储在堆栈中,并且它们没有固定的内存位置。

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

【讨论】:

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

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

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 */
}

如果系统将数组初始化为 0,那么努力就白费了;初始化被函数的其余部分覆盖。 C 尽可能避免隐藏成本。

【讨论】:

  • 如果它们也是简单的变量,那么这些努力就会被浪费掉......
  • @K-ballo:是的,你是对的——但是当变量是较大的数组、结构或结构数组时,成本会更加明显。即使是初始化了几十个整数变量也不是很明显,但是几千个整数值变得很明显。
  • 如果它位于仅使用 4 条指令执行的事物的内部循环中,即使 1 个整数也很明显(+1 指令)。
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多