在此question评论中说:
char arr[10] = { 'H', 'e', 'l', 'l', 'o', '\0'};
andchar arr[10] = "Hello";
are strictly the same thing. – Michael Walz
这让我开始思考。
我知道 "Hello"
是字符串文字。字符串文字以静态存储持续时间存储并且是不可变的。
但如果两者真的相同,则 char arr[10] = { 'H', 'e', 'l', 'l', 'o', '\0'};
也会创建一个类似的字符串文字。
char b[10]= {72, 101, 108, 108, 111, 0};
是否也创建一个具有静态存储持续时间的“字符串”文字?因为理论上是一样的。
char a = 'a';
is the same thing aschar a; ...; a = 'a';
, so your thoughts are correct'a'
is simply written toa
有区别吗:
char a = 'a';
char a = {'a'};
如何/在哪里定义差异?
编辑: 我发现我还不够清楚,我对文字的内存使用/存储持续时间特别感兴趣。我将按原样保留问题,但希望在此编辑中更清楚地说明问题的重点。
最佳答案
I know that "Hello" is string literal. String literals are stored with static storage duraction and are immutable.
是的,但是字符串字面量也是C语言中的一个语法项。 char arr[10] = { 'H', 'e', 'l', 'l', 'o', '\0'};
不是字符串文字,它是一个初始化列表。然而,初始化列表的行为就好像它具有静态存储持续时间,显式 \0
之后的剩余元素被设置为零等。
初始化列表本身以某种方式存储在 ROM 内存中。如果您的变量 arr
也具有静态存储持续时间,它将在 .data
段中分配并在程序启动之前从 ROM 初始化列表中初始化。如果 arr
具有自动存储持续时间(本地),则在调用包含 arr
的函数时,它会在运行时从 ROM 中初始化。
存储初始化列表的 ROM 内存可能与用于字符串文字的 ROM 内存相同,也可能不同。通常有一个称为 .rodata
的段,这些东西在那里结束,但它们也可能在其他段中结束,例如代码段 .text
。
编译器喜欢将字符串文字存储在特定的内存段中,因为这意味着它们可以执行称为“字符串池”的优化。这意味着如果您在程序中多次使用字符串文字 "Hello"
,编译器将为其使用相同的内存位置。它可能不一定对初始化列表进行同样的优化。
关于初始化列表中的 'a'
与 {'a'}
,这只是 C 语言中的语法问题。 C11 6.7.6/11:
The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply,
用简单的英语来说,这意味着一个“非数组”(标量)可以用大括号或不用大括号初始化,它具有相同的含义。除此之外,适用与常规分配相同的规则。
关于c - 关于存储持续时间的数组初始化(字符、字符串、其他)的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49790883/