我认为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不会初始化本地变量的标准参考?
答案 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()是递归的,输出显示堆栈的值,直到你运行堆栈内存(堆栈溢出)。