C 文字串联

C literals concatenation

C 允许我们通过 MACRO 连接文字列表。

#define H "HELLO"
#define W "WORLD"
#define HW H " " W

这将导致 HELLO WORLD 的扩展。

同样可以通过初始化列表实现。

char A[] = "Hello" " " "World";

这也会导致 HELLO WORLD 的扩展。

同样适用于 printf("%s\n", "HELLO" " " "WOLRD");

即使在这里,它也会导致扩展到 HELLO WORLD

在上述所有情况下,我们可以看到,字符串文字是连接在一起的:)

char B[] = "HELLO";
char C[] = " ";
char D[] = "WORLD";
char E[] = B C D;

但同样不会反映在变量中。 为什么会这样?

宏和初始化列表都不对您观察到的内容负责。

当 C 在源代码中发现两个 文字 彼此相邻时,它会将它们连接起来。所以 "hello" "world" 等同于输入 "helloworld".

but same doesn't reflects with variables. why is it so?

几个原因:

  1. 字符串连接由预处理器完成 源文本被解析之前(这是可能的,因为字符串文字有 " 分隔符,使它们在这个级别);
  2. 有一个明确定义的初始化语法,它不允许像 char E[] = B C D;;
  3. 这样的初始化
  4. 类似地,表达式 BCD被转换为指针表达式,而不被视为[=的数组15=];

此外,并不是所有 char 的数组都能保证存储 字符串 。而且您必须为连接的字符串留出存储空间。

What does the standard say about it?

C 程序在 8 个不同的阶段进行翻译(有关详细信息,请参阅 C 2011 Standard 的第 5.1.1.2 节)。

阶段 1 到 6 描述了预处理器的操作;物理源文件字符被映射到 源字符集 ,三字母被转换为等效的单字符,尾随 \ 字符的物理行被拼接成单个逻辑源行,注释替换为单个空白字符,扩展宏,执行预处理指令,并且作为预处理器的最后一步,字符串文字被连接起来。

阶段 7 是编译器实际 解析 按摩过的源文本的地方。

第 8 阶段基本上是链接器步骤。

TL/DR

字符串文字很特殊,预处理器会对其进行特殊处理。