初始化const char*

8

我在一个开源软件中发现了这种用法,但我不理解它是如何工作的。当我将其输出到stdout时,它显示为“版本0.8.0”。

const char version[] = " version " "0" "." "8" "." "0";
7个回答

9

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

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

在字符串拼接发明之前,你必须使用一种相当笨拙的行续延方法,即在每行末尾加上一个反斜杠(并确保它是末尾,因为大多数编译器如果在反斜杠后面有任何空格都不会将其视为行续延)。还有一些丑陋的地方,比如它会扰乱缩进,因为后续行开头的任何空格都可能包含在字符串中。
如果您打算在字符串之间放置逗号,例如初始化指向char的指针数组时,这可能会导致小问题。如果您漏掉了逗号,编译器不会警告您 - 您只会得到一个包含本来应该是两个单独字符串的字符串。

7
这是C89和C++98的一个基本特性,称为“相邻字符串连接”或类似名称。如果两个字符串字面量彼此相邻且之间没有标点符号,则它们会被合并为单个字符串,正如您的输出所显示的那样。在C++98标准的第§2.1节“翻译阶段[lex.phases]”之后,有以下规定:“6 连续的普通字符串文字标记被连接。 连续的宽字符串文字标记被连接。”这是在预处理程序完成后进行的。在C99标准中,相应的部分是§5.1.2.1“翻译阶段”,其中写道:“6 相邻的字符串字面值标记被连接。”在其他任何C或C++标准中,措辞都将非常类似(我知道C++98和C99都已被C++11和C11取代;我只是还没有电子版的最终标准)。

6

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

C和C++标准的引用:

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

(C99, 6.4.5p5) "在翻译阶段6中,由任何相邻且具有相同前缀的字符和字符串字面量令牌指定的多字节字符序列将被连接成一个多字节字符序列。"

对于C++:

(C++11, 2.14.5p13) "在翻译阶段6(2.2),相邻的字符串字面量将被连接。"


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

等同于:

const char version[] = " version 0.8.0";

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

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


2
编译器会自动将紧挨着的字符串字面量拼接在一起(只有空格分隔)... 就好像你写了这样一个字符串。
const char version[] = "version 0.8.0";

编辑:更正为编译器


2

相邻的字符串文字被连接

在指定字符串文字时,相邻的字符串被连接。因此,这个声明:

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

char szStr[] = "1234"; 相邻字符串的连接使得跨越多行指定长字符串变得更加容易:

cout << "Four score and seven years "
"ago, our forefathers brought forth "
"upon this continent a new nation.";


0

只需将字符串一个接一个地放置,编译时它们就会被连接,因此:

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

这是一个奇怪的用法,通常它是允许使用#define字符串的:
#define FOO "World!"

puts("Hello, " FOO);

编译后将与以下代码相同:

puts("Hello, World!");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接