初始化 char 数组 - 是用于初始化数组的字符串,除了存储数组的位置之外,还单独存储在内存中

问题描述 投票:0回答:1

在 Richard Reese 所著的《理解和使用 C 指针》一书中,第 110 页,作者指出

“可以使用初始化运算符来初始化字符数组。在以下示例中,标头数组被初始化为字符串文字中包含的字符:

char header[] = "Media Player";

稍后指出:

“...初始化会将这些字符复制到以 NUL 字符结尾的数组中,如图 5-2 所示,假设声明位于主函数中。

在第 111 页的图 5-2(初始化字符数组)中,它显示了位于堆栈上的头数组及其内存地址,但它还显示了用于初始化位于字符串文字池中的数组的字符串,该数组位于不同的内存地址。

我发现这与我在 K.N. 的书中读到的内容不一致。 King

C 编程现代方法

第二版。在第 281 页上,数组初始化如下

char date1[8] = "June 14";


第 282 页稍后指出:

虽然“June 14”看起来是一个字符串文字,但事实并非如此。相反,C 将其视为数组初始值设定项的缩写。

基于后面的文本和我有限的理解,我认为文本
理解和使用 C 指针

在声明“Media Player”在用于初始化数组时是字符串文字时是不正确的——它不正确似乎只是简单地使用术语“字符串文字”作为字符串的同义词,因为文本然后继续错误地(?)显示“媒体播放器”位于字符串文字池中,并具有自己的内存地址。 我的理解正确吗?

c string string-literals
1个回答
0
投票

在抽象级别,每个字符串文字都会导致创建一个包含字符串文字的字符的数组,根据 C 2018 6.4.5 6:

在翻译阶段 7,值为零的字节或代码被附加到由一个或多个字符串文字产生的每个多字节字符序列。然后,使用多字节字符序列来初始化静态存储持续时间和长度足以包含该序列的数组......

创建和初始化的这个数组与程序可能正在初始化的命名数组不同。例如,在

char header[] = "Media Player";

中,有一个未命名数组,其中包含“Media Player”字符和一个空字符,并且有一个命名数组
header

,它是通过将未命名数组复制到命名数组中来初始化的。

在实际的C实现中,编译器通常会根据上下文以各种方式优化数组初始化:

对于静态存储持续时间的数组,例如在任何函数外部定义的数组或在函数内部使用

static

定义的数组,编译器可能会在对象模块内部创建以其中的数据开头的空间。也就是说,目标文件包含一个或多个部分,这些部分有效地表示“当程序启动时,为该部分分配内存并使用目标模块中的字节对其进行初始化”。一旦数组的内存实际提供给程序,它将用数据进行初始化。
  • 对于无法以其他方式优化的自动存储持续时间的数组,编译器确实需要保留由字符串文字创建的单独数组。然后,每次需要该数组时(例如,调用定义该数组的函数),编译器都会将数据从字符串文字数组复制到指定数组的内存中。
    如果数组很短,编译器可能会将其初始数据构建到程序指令中。许多处理器架构提供包含少量“立即数据”的指令,这些数据可用于构建小常量和短字节序列。
  • 在可以进一步优化的情况下,例如,编译器可以检测到例程仅被调用一次,或者数组是用
  • const
  • 定义的,并且其地址未传递到例程之外,编译器可能会能够像静态数组一样对待它。
© www.soinside.com 2019 - 2024. All rights reserved.