c语言中的字符串拼接,一种奇怪的现象



最近,我看到了一个C语言代码,如下所示:

printf("%sn", "1234" "qwer");
// output: 1234qwer
snprintf(buffer, sizeof(buffer), "bvcx" "mju");
// buffer data: bvcxmju

说实话,这对我来说太神奇了。在那之前,我不知道字符串可以用"1234" "qwer"格式粘贴。为什么它能运行?然后,我尝试这个"chara[]=";1234"qwer’,gcc返回错误!那么,有人能解释这种现象并解释理论吗?

您所看到的内容长期以来一直是C语言语法的一部分。经过预处理和注释删除后,字符串文本可以拆分为多个仅用空格分隔的部分。此语法启用例如:

  • 在多行上写入长字符串文字:

    char message[] = "This is a long message that can be split on "
    "multiple lines for readability";
    
  • 组合定义为宏的字符串片段:

    printf("The value of i32 is %" PRId32 "n", i32);
    
  • 如果并置,则分隔具有不同含义的字符串内容:

    char s1[] = "This is ESC 4: x1B" "4";
    char s2[] = "so is this: 334 and this: 33""4";
    char s3[] = "but not this: 334";
    char s4[] = "nor this: x1B4";
    
  • 组合字符串化宏参数

作为翻译阶段的一部分,相邻的字符串文字总是连接到一个单独的文字中。参见C17 6.4.5/5:

在翻译阶段6中,由任何相邻字符序列和前缀相同的字符串文字标记指定的多字节字符序列被连接到单个多字节字符串中。

形式上,转换阶段6发生在宏扩展之后,但在预处理器标记转换为标记之前。例如,这意味着
sizeof "hello " "world"产生结果12,相当于:
sizeof "hello world"

实际上,这在编写各种";字符串化";宏,示例:

#include <stdio.h>
#define STRINGIFY(x) #x
#define STRINGIFY_CONCAT(a,b) STRINGIFY(a) " " STRINGIFY(b)
int main (void)
{
puts(STRINGIFY_CONCAT(hello,world));
}

每当您必须使用十六进制转义序列并需要终止它们时,这也是一个有用的功能,因为C允许它们具有可变长度:puts("xABBA")puts("xAB" "BA")将给出不同的输出。

最新更新