在 C 中,字符串和以 Null 结尾的字符数组之间有什么区别吗?



想问的是字符串是可以在 c 中互换的以 null 结尾的字符数组。 喜欢

char string3[] = "abc";
char string4[4] = {'a','b','c',''};
if(!strcmp(string3,string4)){
printf("yes");
}

甚至 strcmp 也给出了是的。因此,只有初始化的差异,或者那里深处存在一些差异。

char string3[] = "abc";

正好是

char string4[4] = {'a','b','c',''};

而且没有区别。

但是,请注意

//  now it's a pointer
//   |
//   v
char *string3b = "abc";

char string4[4] = {'a','b','c',''};

等同。每当您编写字符串并且不使用它初始化数组(指针不是数组)时,编译器都会为您创建一个数组。第一个基本等价于:

static const char _magic_compiler_variable_for_abc_string[4] = {'a','b','c',''};
char *string3b = (char*)_magic_compiler_variable_for_abc_string;

因此,字符串被分配到其他地方,string3b只保存指向它的指针。由于字符串变量是const的(即使指针不是常量),因此在这种情况下不允许编辑字符串。编译器可以在您编写"abc"的任何地方使用相同的_magic_compiler_variable_for_abc_string,也可以创建单独的。

char string3[] = "abc";
char string4[] = {'a','b','c',''};

主要区别在于字符串文本初始值设定项由多字节字符序列组成,而数组初始值设定项列表由一系列整数常量表达式组成,每个表达式由多字节字符常量组成。如果任何字符不能用单个char表示,它们的内容就会不同。string3[]将超过 4 个字节,string4[]长度正好为 4 个字节,但其某些元素的值将被截断。它不应该影响字符abc这些字符是基本字符集的一部分,因此应该适合单个char

例如,在我的系统上,C 使用 UTF-8 作为源和执行字符集1,以下程序:

#include <stdio.h>
int main(void)
{
char string1[] = "αβγ";
char string2[] = { 'α', 'β', 'γ', '' };
printf("sizeof string1 = %zu, sizeof string2 = %zun",
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[] = { 'α', 'β', 'γ', '' };
|                     ^~~
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[] = { 'α', 'β', 'γ', '' };
|                          ^~~
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[] = { 'α', 'β', 'γ', '' };
|                               ^~~
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', '' };

如果数组初始值设定项需要是 UTF-8 序列而不考虑执行字符集,则使用显式u8前缀字符串文本初始值设定项将更具可读性:

char string6[] = u8"αβγ";

无论执行字符集如何,string5[]string6[]的初始内容都是相同的,并且当且仅当执行字符集为 UTF-8 时,string1[]的初始内容才会相同。

<小时 />

1我所说的"字符集">实际上是指字符集加编码,字符集是从指定的编码推断出来的。 即"UTF-8"是指 UCS 字符集加上 UTF-8 传输编码。

2编译器在编译给定示例时不需要发出任何诊断消息,但有些编译器选择这样做。

最新更新