为什么字符串文字不是字符串?

时间:2020-06-06 14:21:48

标签: c string null language-lawyer string-literals

我在C标准中关于字符串文字的这一部分苦苦挣扎,尤其是它的第二部分:

在翻译阶段7中,一个或多个字符串文字产生的每个多字节字符序列附加一个零值的字节或代码。80)


80)字符串文字可能不是字符串(请参见7.1.1),因为可以通过\0转义序列将空字符嵌入其中。

来源:ISO / IEC 9899:2018(C18),§6.4.5/ 6,第51页

我不理解这种解释-“ 因为可以通过\0转义序列将空字符嵌入到其中。”。


要查看参考的第7.1.1节中有关“字符串”的定义,请指出:

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。

来源:ISO / IEC 9899:2018(C18),§7.1.1/ 1,第132页

我考虑过重点可能放在“ can ”上,这样一来,字符串文字不必包含/嵌入空字符,而需要使用字符串。

但是然后我又问自己:如果字符串文字中没有以字符串结尾的空字符,那么如何才能将其用作字符串来确定字符串的结尾(字符串操作函数需要此字符串) )?

我现在完全在画空白。


注意:我知道一个字符串文字存储在只读存储器中,无法修改,并且字符串是NUL终止的一系列字符的通用术语,可变或不可变。

因此,我的问题不是:“ 字符串和字符串文字之间有什么区别?

我的问题是:

  • 为什么/怎么不能将字符串文字当作字符串?

根据我的关注,到目前为止:

  • 是真的,字符串文字可以省略NUL字节吗?

我本人想问这个问题,但是在发布之前不久,我就知道了。我之所以感到困惑,是因为报价内的措词错位。

但是我决定不删除该问题的草稿,因为它可能对将来的读者有用,并提供一个问答环节。

随时发表评论和提示。


相关内容:

2 个答案:

答案 0 :(得分:3)

您想得太多。

“字符串是一个连续的字符序列,以第一个空字符结尾,并包括第一个空字符。”

来源:ISO / IEC 9899:2018(C18),§7.1.1/ 1,第132页

表示“字符串”仅扩展到第一个空字符。 null后面可能存在的字符不是字符串的一部分。但是

“ 80)字符串文字可能不是字符串(请参见7.1.1),因为可以通过\ 0转义序列将空字符嵌入其中。”

清楚表明字符串文字可能包含嵌入的null。如果是的话,字符串文字 AS 就不是字符串-字符串只是字符串文字的前缀,直到第一个null为止

答案 1 :(得分:0)

让我们看看C18§6.5.1/ 3中同一部分中“ 字符串文字”的定义:

字符串文字是由双引号引起的零个或多个多字节字符的序列,例如"xyz"

因此,字符串文字仅由引号内的字符(裸字符串内容)组成。它没有附加的\0。如§6.5.1/ 6中所述:

在翻译阶段7中,一个或多个字符串文字产生的每个多字节字符序列附加一个零值的字节或代码。80)


让我们举个例子:

"foo" string文字,而不是 string ,因为"foo"不包含 embedded null字符。

"foo\0"字符串文字 string ,因为文字本身在字符序列的末尾包含一个空字符。


请注意,您无需在字符串文字的末尾显式插入空字符即可将其更改为 string 。如前所述,它在程序翻译过程中被隐式附加。

手段

const char *s = "foo";

等于

const char *s = "foo\0";

我承认,以下句子:

字符串文字可能不是字符串(请参见7.1.1),因为可以通过\0转义序列将空字符嵌入其中。

在上下文中有点混乱和不合逻辑。最好这样写:

字符串文字可能不是字符串(请参见7.1.1),因为空字符可能不是(或不需要 )通过\0转义序列嵌入其中。

或者:

字符串文字可能 不是 是字符串(请参见7.1.1),因为{{1可以将空字符嵌入其中}}转义序列。


正如@EricPostpischil在其comment中指出的那样,脚注的含义可能完全不同。

这意味着,如果 string文字在其中包含一个空字符,但不包含在结尾(如 string 所必需),则字符串常量不等同于 string

F.e .: 字符串文字

\0

不是 string ,因为它包含 string文字内的第一个空字符 embedded ,但不是在其末尾