我的csapp书中说,如果初始化了全局和静态变量,则它们将包含在ELF可重定位目标文件的.data节中。
所以我的问题是,如果某些foo.c
代码包含
int a;
int main()
{
a = 3;
}`
和example.c
包含
int b = 3;
int main()
{
...
}
是否只有b
被认为已初始化?换句话说,初始化意味着在同一行中声明和定义吗?
答案 0 :(得分:3)
它的意思恰恰是它所说的。初始化的静态存储持续时间对象将在调用主函数之前设置其初始值。未初始化将被清零。该语句的第二部分实际上是依赖于实现的,并且实现拥有将其归档方式的全部自由。
在声明不带关键字extern
的变量时,您也总是要对其进行定义
答案 1 :(得分:3)
它们得到zero initialized或常量的形式(简而言之:如果右侧是编译时常量表达式)。
如果允许,则首先进行常量初始化(请参见常量 这些情况列表的初始化)。在实践中, 常量初始化通常在编译时执行,并且 预先计算的对象表示形式存储为 程序映像。如果编译器不这样做,它仍然必须 确保此初始化发生在任何动态之前 初始化。
对于所有其他非局部静态变量和线程局部变量,零 初始化发生。在实践中,要 被零初始化放置在程序的.bss段中 映像,该映像不占用磁盘空间,并且由操作系统清零 加载程序时。
总而言之,如果实现无法对它进行常量初始化,那么它必须首先进行零初始化,然后在进行任何动态初始化之前对其进行初始化。
答案 2 :(得分:1)
我将以一般且完整的方式回答此问题,而不是针对任何编程语言
在声明,定义和初始化之间有很多混乱。有时它们看起来都相似,有时却完全不同。
在理解差异之前,了解以下两点非常重要:
声明,定义和初始化之间的区别 从一种编程语言到另一种编程语言都不同。每个程序都有 这是自己做这三件事的方式。 定义,声明或初始化也会影响差异 在他们三个之间。 “事物”可以是变量,类或 一个功能。它们都有不同的定义含义, 声明和初始化。一旦我们了解了以上两个 事情,大多数疑虑都消除了,我们不再寻求确切的 差异,因为它不存在。
一般术语(与任何语言或“事物”无关)
该声明表示我们正在对计算机说,这种“东西” (可以是变量,函数或类)存在,但我们不知道 哪里。将来,我们可能会告诉您,但现在它刚刚存在 某处。简而言之,我们在声明时不会分配内存。 我们可以多次声明“事物”。 这个定义意味着我们对计算机说,这个“东西”需要内存,并且需要放置在某个地方。简单来说 换句话说,定义意味着我们已经为其分配了内存。我们可以定义 只有一次 初始化意味着无论我们的“东西”是什么,我们都给它一个初始值。该“事物”必须位于某个内存位置,并且 如果我们将该位置保留为空,则可能是存在错误和错误的地方。 初始化并非总是必要的,但很重要。
许多人认为声明+定义=初始化。
这没错,但并非在所有地方都正确。它仅对同样使用C ++或C语言的变量也正确。
在python中,没有声明的概念。我们不需要在其中声明任何内容。
这三个词的一般含义在任何地方都是有效的,但是执行的方式因语言和“事物”而异。
希望它会有所帮助:)
答案 3 :(得分:1)
在代码段中:
int a;
int main()
{
a = 3;
}
a
未初始化;它是已分配。分配是代码的运行时执行。例如,应该多次调用main
(不是,但是任何用户函数都可以),那么每次调用该函数时,a
都设置为3。
第二个片段是全局变量b
的初始化,它将被放置在.data
段中。
答案 4 :(得分:0)
.bss
结尾。 .data
结尾。注意:C标准保证,如果程序员没有显式地初始化具有静态存储持续时间的变量,例如static int a;
,那么它将隐式地初始化为零(sup> 1)。因此a
以.bss
结尾。
示例here。
1) C11 6.7.9
如果具有静态或线程存储持续时间的对象未初始化 明确地,然后:
- 如果具有算术类型,则将其初始化为(正数或无符号)零;