以空终止符结尾的字符串字面值是否包含额外的空终止符?

51
例如:
char a[] = "abc\0";

标准C是否规定,即使字符串末尾已经有一个零值字节,也必须追加另一个值为0的字节?因此,sizeof(a)是4还是5?


1
你的问题中的英语没有任何问题。但是你不能通过尝试来找到答案吗? - Barmar
4
如果你想表达得更明确,可以写成:char a[] = {'a','b','c','\0'};。这不被声明为字符串字面值,因此不会自动追加额外的空字符来终止字符串。 - Coder_Dan
或者,您可以编写 char a[4] = "abc\0"; - nwellnhof
后者可能看起来有点不对,因为标准规定会添加一个额外的 '\0',使得字符串字面值的大小为 5 个字符,因此似乎太大了以至于不能用在一个 4 字符数组中。但是,在情况下初始化程序对于固定大小的数组过大,多余的元素将被简单地忽略/未用于初始化 (§6.7.8 第14段),在这种情况下,这是可以的,但我会避免写成这样。 - stefanct
2个回答

77
所有字符串字面值都有一个隐含的空终止符,无论字符串内容如何。
标准(6.4.5字符串字面值)中写道:
“从字符串字面值或多个字符串字面值得到的每个多字节字符序列都将附加一个值为零的字节或代码。”
因此,字符串字面值 "abc\0" 包含了隐含的空终止符,除了显式的空终止符之外。因此,数组 a 包含5个元素。

所以,数组a包含5个元素。 你是指4个元素吗? - Bikal Lem
30
不,5是正确的。{'a','b','c','\0','\0'} - Dietrich Epp
在C语言中,有一种隐式空终止符的例外情况,例如char s[3] = "abc";,这里s将不会有一个空终止符。(顺便说一句,在C++中这将是一个编译错误)。请参见此答案 - johan

0

指出与C字符串相关的一些细微差别。

字符数组sizeof将为5,但字符串通常被视为3个字符+1个空终止符。多余的空终止符不会被看到。

这是因为字符串被遍历直到第一个空终止符被遇到。这就是为什么strlen将是3而不是4的原因。计算了3个字母,当它遇到表示字符串结尾的空终止符时,它就停止了。

当将char[]传递给函数时,它将衰减为char*,因此原始char[]的大小为5的事实进一步丢失。

然而...如果将sizeof(a)传递给函数,则额外的null可能会导致问题,并且当然不应包含在字符串文字中。

#include <string.h>
#include <stdio.h>

void main() {
    char a[] = "abc\0";
    printf("sizeof: %lu\n", sizeof(a));
    printf("strlen: %lu\n", strlen(a));
}

输出:

sizeof: 5
strlen: 3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接