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

时间:2014-01-16 02:06:45

标签: 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不会初始化本地变量的标准参考?

7 个答案:

答案 0 :(得分:10)

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

  

如果未初始化具有自动存储持续时间的对象   显然,它的价值是不确定的。

     

如果未初始化具有静态存储持续时间的对象   明确地说:

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

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

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

int n = 0;

(顺便提一下,您错过了必需的#include <stdio.h>main的正确声明是int main(void)。)

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分:-1)

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

答案 6 :(得分:-1)

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

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