ANSI C的一个特性是相邻的字符串常量被自动合并成一个字符串,这就省掉了书写多行信息时必须在行末尾加’\‘的做法,后续的字符串可以出现在每行的开头。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

int main(){

printf("hello \
world \
\n");

printf("hello "
"world"
" \n");

return 0;
}

运行输出:

1
2
hello   world   
hello world

可见行末加’'的做法,把下一行的缩进也包含到字符串里了,要实现一样的效果,得:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

int main(){

printf("hello \
world \
\n");

printf("hello "
"world"
" \n");

return 0;
}

运行输出:

1
2
hello world 
hello world

自动合并是在编译时自动合并,除了最后一个字符串外,其余每个字符串末尾的’\0’字符会被自动删除。
然而,这种自动合并在字符串数组初始化时要特别注意。字符串数组在初始化时,如果不小心漏掉了一个逗号,编译器将不会发出错误信息,而是悄无声息的把两个字符串合并在一起。代码示例:

1
2
3
4
5
6
7
8
9
10
int main(){
char *word[] = {
"pen",
"class",
"note" //这里漏掉逗号
"book",
};
printf("%s",word[2]);
return 0;
}

运行输出:

1
notebook

这样,word[2]由原来的”note”变为”notebook”。而更可怕的错误是,字符串数组的长度比预期的少了一个,如果在程序中访问或修改word[3],就是数组越界,访问或修改了其他的内容。示例:

1
2
3
4
5
6
7
8
9
10
int main(){
char *word[] = {
"pen",
"class",
"note" //这里漏掉逗号
"book",
};
printf("%s",word[3]);
return 0;
}

运行输出:

1
?@

关于数组、枚举、结构体等变量声明时最后一个逗号的问题:
在上述代码中,”book”后面有一个逗号。这个逗号不是打字错误,而且最早的C语法中继承下来的东西,是计算机发展早期非常古老的一种写法,这么写的目的是让以后的程序维护人员少输入一个逗号,现代的C语言中一般已经不这么用了。
当然,现在加不加效果都一样,都无所谓的,对代码本身来说没有什么意义。

These extra commas are permitted but are not required.