未初始化的整数在c中总是默认为0吗?
Posted
技术标签:
【中文标题】未初始化的整数在c中总是默认为0吗?【英文标题】:Is un-initialized integer always default to 0 in c? 【发布时间】:2011-09-06 23:05:05 【问题描述】:我正在阅读nginx的源代码,发现它没有初始化很多数值变量,包括ngx_int_t ngx_last_process;
,这里ngx_int_t
定义为long int
#if 0
ngx_last_process = 0;
#endif
所以这里@Igor Sysoev 认为没有必要进行初始化?
但在程序中它假设默认值为0
:
for (s = 0; s < ngx_last_process; s++)
if (ngx_processes[s].pid == -1)
break;
是否保证未初始化的变量在 c 中将具有 0
值?
【问题讨论】:
【参考方案1】:在文件范围声明的变量(如int
)被初始化为0。
例子
int i;
int main()
int x;
printf("%d",i); // prints 0
printf("%d",x); // prints some unspecified value
是否保证未初始化的变量在c中的值为0?
不!这不适用于在函数范围内声明的变量。
【讨论】:
printf("%d",x);
语句还可以使您的 NUM LOCK 灯闪烁(尤其是如果您的架构允许在int
s 中表示陷阱)
@pmg:是的!毕竟行为是未定义的。
有点错误。您可以在文件范围内声明 int x;
,并且在其他地方仍有定义int x=1;
。 :)
我确信这就是 C 的工作方式,但经历了一些不同的事情。在一个小程序中,x 为零。由于 x 在随后的处决中为零,我不认为它为零是偶然的。是不是较新的编译器会导致不同的行为?【参考方案2】:
External 和 static 变量默认初始化为零,这是有保证的。 Automatic 和 register 没有显式初始化器的变量将具有不确定的值(未指定的值或陷阱表示)。
来自标准:
C89
6.5.7:
如果具有静态存储持续时间的对象未初始化 显式地,它被隐式初始化,就好像每个具有 算术类型被分配 0 并且每个具有指针类型的成员 被分配了一个空指针常量。如果一个对象有 自动存储持续时间未显式初始化,其值为 不确定。
C99
6.2.4,§5:
对于这样一个没有变长数组类型的对象,它的生命周期会延长 从进入与其关联的块直到该块的执行结束 无论如何。(进入封闭块或调用函数会暂停,但不会结束, 当前块的执行。)如果块是递归进入的,一个新的实例 每次都会创建对象。对象的初始值是不确定的。如果 为对象指定初始化,每次声明时执行 在执行块时达到;否则,每个值都变得不确定 到达声明的时间。
6.7.8,§10:
如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。如果具有静态存储持续时间的对象未显式初始化,则:
——如果是指针类型,则初始化为空指针;
——如果是算术类型,则初始化为(正或无符号)零;
——如果是聚合,则每个成员都根据这些规则(递归地)初始化;
——如果是联合,则根据这些规则(递归地)初始化第一个命名成员。
3.17.2,§1:
不确定值:未指定的值或陷阱表示
3.17.3,§1:
未指定值:相关类型的有效值,其中本国际标准对在任何情况下选择哪个值没有要求。注意 未指定的值不能是陷阱表示。
【讨论】:
"(一些垃圾值" ...或陷阱表示或任何东西...")" @pmg,trap representation
是什么?
“未定义值”应为“不确定值”以使用 C99 标准的措辞。陷阱表示是内存中的一种位模式,如果您使用char
以外的类型的左值访问它,则会导致未定义的行为。
@cpuer:trap representation
是不代表有效值的位排列。大多数当前的计算机都对不同的有效值使用所有位表示,尤其是在整数类型中,但语言并没有强制要求。 陷阱表示不是垃圾值。【参考方案3】:
这取决于变量的分配方式。静态分配的变量初始化为零,而分配在堆栈上或malloc()
的变量则不是。
【讨论】:
【参考方案4】:automatic
(局部)变量不保证为零,可以包含垃圾。
global
变量和static
变量保证为零。
【讨论】:
以上是关于未初始化的整数在c中总是默认为0吗?的主要内容,如果未能解决你的问题,请参考以下文章