char string3[] = "abc";
char string4[] = {'a','b','c','\0'};
主要区别在于字符串字面量初始值设定项由多字节字符序列组成,而数组初始值设定项列表由整数常量表达式序列组成,每个表达式均由多字节字符常量组成。如果任何字符不能由单个char 表示,则它们的内容会有所不同。 string3[] 将长于 4 个字节,string4[] 将恰好是 4 个字节长,但其中一些元素的值被截断。它不应该影响字符a、b、c,它们是基本字符集的一部分,因此应该适合单个char。
例如,在我的系统上,C 使用 UTF-8 作为源和执行字符集1,下面的程序:
#include <stdio.h>
int main(void)
{
char string1[] = "αβγ";
char string2[] = { 'α', 'β', 'γ', '\0' };
printf("sizeof string1 = %zu, sizeof string2 = %zu\n",
sizeof string1, sizeof string2);
return 0;
}
编译(带有警告2)并产生输出:
sizeof string1 = 7, sizeof string2 = 4
来自 gcc 10 的警告是:
foo.c: In function ‘main’:
foo.c:6:21: warning: multi-character character constant [-Wmultichar]
6 | char string2[] = { 'α', 'β', 'γ', '\0' };
| ^~~
foo.c:6:21: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘52913’ to ‘-79’ [-Woverflow]
foo.c:6:27: warning: multi-character character constant [-Wmultichar]
6 | char string2[] = { 'α', 'β', 'γ', '\0' };
| ^~~
foo.c:6:27: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘52914’ to ‘-78’ [-Woverflow]
foo.c:6:33: warning: multi-character character constant [-Wmultichar]
6 | char string2[] = { 'α', 'β', 'γ', '\0' };
| ^~~
foo.c:6:33: warning: overflow in conversion from ‘int’ to ‘char’ changes value from ‘52915’ to ‘-77’ [-Woverflow]
如果假定执行字符集为 UTF-81,则字符串字面量初始化器 "αβγ" 可以通过将每个字符展开为其字节序列来更改为数组初始化器列表:
char string5[] = { '\xce', '\xb1', '\xce', '\xb2', '\xce', '\xb3', '\0' };
如果无论执行字符集如何,数组初始值设定项都需要是 UTF-8 序列,则使用显式 u8-prefixed 字符串字面量初始值设定项会更具可读性:
char string6[] = u8"αβγ";
string5[]和string6[]的初始内容无论执行字符集如何都是相同的,并且当且仅当执行字符集是UTF-8时才会与string1[]的初始内容相同。
1“字符集”我真正的意思是一个字符集加上一个编码,字符集是从指定的编码推断出来的。 IE。 “UTF-8”是指 UCS 字符集加上 UTF-8 传输编码。
2 编译器在编译给定示例时不需要发出任何诊断消息,但有些人选择这样做。