const char* initialization

const char* initialization

本文关键字:initialization char const      更新时间:2023-10-16

这是我在开源软件中发现的一个用法。我不明白它是怎么工作的。当我把它输出到stdout时,它是"版本0.8.0"。

const char version[] = " version " "0" "." "8" "." "0";

它被称为字符串串联——当你在源代码中把两个(或多个)带引号的字符串放在一起,它们之间没有任何东西时,编译器会把它们放在一个字符串中。这最常用于长字符串——任何超过一行长的字符串:

char whatever[] = "this is the first line of the stringn"
    "this is the second line of the stringn"
    "This is the third line of the string";

在字符串串联被发明之前,你必须用一个相当笨拙的行延续来实现这一点,在每行的末尾放一个反斜杠(并确保它是末尾,因为如果反斜杠后面有空格,大多数编译器不会将其视为行延续)。它去掉缩进也很难看,因为后续行开头的任何空格都可能包含在字符串中。

如果您打算在字符串之间放置逗号,例如在初始化指向char的指针数组时,这可能会导致一个小问题。如果你漏掉了一个逗号,编译器不会警告你——你只会得到一个字符串,其中包括两个单独的逗号。

这是C89和C++98的一个基本特性,称为"相邻字符串连接"或其附近。

基本上,如果两个字符串文字彼此相邻,中间没有标点符号,则它们将合并为一个字符串,如输出所示。


在C++98标准中,第2.1节"翻译阶段[lex.Phases]"说:

6连接相邻的普通字符串文字标记。连接相邻的宽字符串文字标记。

这是在预处理器完成之后。

在C99标准中,相应的章节是§5.1.2.1"翻译阶段",其中写道:

6连接相邻的字符串文字标记。

在你能掌握的任何其他C或C++标准中,措辞都非常相似(我确实认识到C++98和C99都被C++11和C11取代了;我只是还没有最终标准的电子副本)。

C++标准实现的一部分规定,相邻的字符串文字将连接在一起。

来自C和C++标准的报价:

对于C(引用C99,但C11在6.4.5p5中有类似内容):

(C99,6.4.5p5)"在翻译阶段6,多字节字符由任何相邻字符序列指定的序列,以及前缀相同的字符串文字标记连接到单个多字节字符序列。"

对于C++:

(C++11,2.14.5p13)"在翻译阶段6(2.2),相邻字符串文字连接在一起。"

const char version[] = " version " "0" "." "8" "." "0";

与相同

const char version[] = " version 0.8.0";

编译器将相邻的字符串文字连接起来,形成一个更大的字符串文字。

附带说明一下,const char*(在您的标题中)与char char[](在您发布的代码中)不同。

编译器自动将相继写入的字符串文字连接起来(仅用空格分隔)。。就好像你写了

const char version[] = "version 0.8.0";

EDIT:已更正预处理器到编译器

连接相邻的字符串文字:

当指定字符串文字时,相邻的字符串会连接起来。因此,本声明:

char szStr[]="12"34";与此声明相同:

char szStr[]="1234";这种相邻字符串的串联使它易于指定跨多行的长字符串:

cout<lt;"四分七年"
"以前,我们的祖先创造了"
"在这个大陆上,一个新的国家。";

只需在编译时一个接一个地放置字符串即可将它们连接起来,因此:

"Hello" ", " "World!" => "Hello, World!"

这是一个奇怪的功能用法,通常是为了允许使用#define字符串:

#define FOO "World!"
puts("Hello, " FOO);

将编译为相同的:

puts("Hello, World!");