\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
,这将指示实际数据的结束位置。
据我了解,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
,这将指示实际数据的结束位置。