C语言 为什么布尔数组的元素在文件范围内声明时初始化为false,而在块范围内声明时未定义?[副本]

2ul0zpep  于 2023-05-28  发布在  其他
关注(0)|答案(4)|浏览(105)

此问题已在此处有答案

Why are global and static variables initialized to their default values?(5个答案)
2天前关闭。
我在初始化一个布尔数组时遇到了一些问题,发现this answer声明“如果在文件作用域声明,元素的初始值为false(即0),如果在块作用域声明,则不确定。”这解决了引起我的问题的问题,但现在我想知道,为什么会这样?

lnlaulya

lnlaulya1#

因为标准是这样规定的。
根据C标准C11 6.7.9/10:
“...如果具有静态或线程存储持续时间的对象未显式初始化,则:

  • 如果是指针类型,则初始化为空指针;
  • 如果是算术类型,则初始化为(正的或无符号的)零;”
apeeds0o

apeeds0o2#

在文件范围内声明的变量可以在加载时初始化,此时可执行映像被带入内存。这几乎没有成本。
但是在块范围内初始化变量将需要在每次进入块时使用memset或memcpy,可能什么都没有,并且可能对成本产生巨大影响。

83qze16e

83qze16e3#

  • 所有在函数外声明的变量或使用存储类说明符static的变量都有 * 静态存储持续时间 *。
  • 如果程序员没有显式初始化一个具有静态存储持续时间的变量,则在调用main()之前将其初始化为零。如果将bool初始化为零,则与将其初始化为false是一样的。
  • 而所有在函数内部声明或作为函数参数(通常称为“局部变量”)的变量都有 * 自动存储期限 *。如果程序员没有显式地初始化它们,它们的值就是“不确定的”,本质上意味着不可预测的垃圾值。
u7up0aaq

u7up0aaq4#

原因是没有初始化器的“静态”存储持续时间的对象被初始化为零或空指针(如果适用)[递归地应用于:数组元素、结构成员、联合的第一个成员]。
在文件作用域声明的数组具有“静态”存储持续时间,与它们是使用关键字externstatic还是不使用关键字static声明无关。
在函数中声明的数组具有“自动”存储持续时间,这意味着它们没有初始化并且包含垃圾值。
至于 * 为什么 * 会这样,我只能推测,但原因很可能是以下几点:

  • 具有“静态”存储持续时间的对象的初始化只需要执行一次
  • 具有“自动”存储持续时间的对象的初始化需要在每当进入相应函数时进行,因此存在性能成本。

标准(C17)的相关部分是(草案,6.7.9 ¶10):
如果没有显式初始化具有自动存储持续时间的对象,则其值不确定。如果具有静态或线程存储持续时间的对象未显式初始化,则:

  • 如果是指针类型,则初始化为空指针;
  • 如果是算术类型,则初始化为(正的或无符号的)零;[...]

相关问题