\0 字符是实际的 0x00 字节吗?为什么这不会破坏其中包含“0”的 int 数组?

Is the \0 character an actual 0x00 byte? Why doesn't this break int arrays with a "0" in them?

据我了解,C 中的数组结尾在内存中由“[=10=]”字符标记。

但这究竟是什么?如果我有一个字符串“ABC”,它的字符数组的内存区域会像这样吗:

0x41 0x42 0x43 0x00?

因为如果是这样,是不是意味着 int[] 数组不能包含 0,因为那会标志着它过早结束? 即,[1, 2, 0, 3, 4],存储为字节 0x01 0x02 0x00 0x03 0x04,然后在遇到 0x00 时,程序会说“哦,看,这是一个 2 字节长的数组,我们到这里就完成了”?

它实际上是一个零(通常至少,我不确定标准是如何定义它的)。 使它“特殊”的是类型(char,或者更确切地说是被视为字符串的 char 数组)和约定,而不是零本身,即:标准库函数依赖于以 null 结尾的字符串。但是人们可以自由地编写自己的行为不同的实现。现在,在实践中这样做可能不可行,但在技术上是可行的。

另请注意,也可以使用未终止的 char 数组。根本不是字符串。

From what I understand, array ends in C are marked in memory by the "[=24=]" character.

你错了。

如果数组的最后一个元素显式或隐式设置为零,则数组的末尾可以用零字符标记。

例如,如果您要声明一个整数数组,例如

int a[] = { 1, 2, 3, 4, 5 };

那么数组的两个元素都不存储零。但是如果你将数组声明为

int a[6] = { 1, 2, 3, 4, 5 };

那么实际上数组的最后一个元素将被隐式初始化为零。

至于像 "ABC" 这样的字符串文字,它们被存储为带有附加零字符的字符数组。例如,字符串文字 "ABC" 作为未命名数组存储在内存中,如

char unnamed_literal[] = { 'A', 'B', 'C', '[=12=]' };

此外,您还使用

之类的字符串文字初始化字符数组
char s[] = "ABC";

然后字符串文字的所有字符(包括终止零)都用作已初始化数组元素的初始值设定项。

那就是如果你之后会写

printf( "sizeof( s ) = %zu\n", sizeof( s ) );

那么这条语句输出值4.

但是在 C 中,当字符数组由字符串文字初始化时,您可以从初始化程序中排除终止零。例如

char s[3] = "ABC";

在这种情况下,初始化的字符数组将不包含字符串(以零字符终止的字符序列 '[=20=]'),数组 s 将仅包含三个字符 { 'A'、'B'、'C'}。你可以检查这个,如上所示,就像

printf( "sizeof( s ) = %zu\n", sizeof( s ) );

在这种情况下,将输出值 3

至于你的说法

[1, 2, 0, 3, 4], stored as bytes 0x01 0x02 0x00 0x03 0x04, then upon encountering the 0x00, the program would say "oh look it's a 2 byte long array, we're done here"?

然后注意,在这种情况下,两个程序都没有说什么。这是一个适当定义的函数,可以检查数组是否包含等于零的元素。

例如,C 标准中存在的此类函数依赖于字符数组是否包含字符串(以零字符 '\0' 终止的字符序列)。例如,标准函数 strlen returns 在遇到终止零之前存储在字符数组中的字符数。但是这个值并不表示数组的结尾。字符数组可以比其中存储的字符串的长度大很多。

对于整数数组,C 标准中没有此类函数。例如,如果零表示数组中实际元素的结尾,您可以自己为整数数组编写这样的函数。但一般来说,零通常是一个有效的整数值,它可以与整数数组元素中的其他值一起出现。

From what I understand, array ends in C are marked in memory by the "[=20=]" character.

C 语言中数组没有任何结束标记。

只有 C strings 是 char(或 wchar_t 对于多字节字符集)数组,字符串的结尾由 null character

来自 C 标准:

A byte with all bits set to 0, called the null character, shall exist in the basic execution character set; it is used to terminate a character string.

因此 null character 的值为 0(或十六进制的 0x00)。字符常量是 '[=14=]'(或 L'[=15=]' for wchar_t strings)

Because if so, wouldn't that imply that an int[] array couldn't contain a 0

不,因为 null character 仅终止 C strings

Why is it only necessary for those?

因为包含字符串的 char 数组可能比字符串本身大得多,您需要知道字符串在哪里结束。

当然,您的算法可能会为其他类型引入 sentinel value,这将指示实际数据的结束位置。