c-字符串文字末尾的null字符



我写了两个版本的代码来练习如何制作字符数组,我希望结果是一样的。

版本1:

int main(void)
{
char a[7] = "and";
printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

版本2:

int main(void)
{
char a[7];
a[1] = 'a';
a[2] = 'n';
a[3] = 'd';
printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

然而,我得到的结果是:

版本1:

size: 7   length: 3

版本2:

size: 7   length: 4

据我所知,字符串以null字符结尾,字符串文字中的null字符是隐含的,但为什么它会消失呢?为什么它没有作为最后一个元素包括在内,因为版本1中的长度显示为3?

实际上strlen应该排除空字符,所以输出3是正确的。第二个版本的问题是a[7]没有初始化,因此它的值可能是任意的。在这种情况下,第5个值为0,而第0个值不为0,因此输出为4。请注意,在第二个版本中,您使用了错误的索引——数组的索引从0开始,而不是从1开始。

如果你想在第二个版本中实现这一点,请这样重写:

int main(void)
{
char a[7] = {0};
a[0] = 'a';
a[1] = 'n';
a[2] = 'd';
printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

这将显式地将a中的第一个值初始化为0,并隐式地使所有其他值也为零。

在第二种情况下

int main(void)
{
char a[7];
a[1] = 'a';
a[2] = 'n';
a[3] = 'd';
printf("size: %d   length: %d",sizeof(a), strlen(a) );
}

你很幸运

  • a[0]不包含0(即''或null(:您会看到值0作为长度
  • a[4]实际上有一个空值,否则,您的计算机可能已经被烧毁

换句话说,对于具有自动存储的局部变量,如果未初始化,则值是不确定的。不能保证0填充(充当null终止符(,因此将数组用作字符串(例如:strlen()的参数(可能会访问超出绑定的内存并调用未定义的行为。

sizeof测量某个事物的内存大小。strlen计算c字符串的长度(长度定义为字符序列的长度,不包括以nul结尾的字符(。这里你的c字符串比用来存储它的内存短。

sizeof是作为编译时计算的C运算符。

strlen是一个库函数,在运行时调用。

strlen(3)

描述strlen((函数计算字符串s的长度。

RETURN VALUESstrlen((函数返回终止NUL字符。

请注意,第二个示例未定义,因为字符数组未初始化,strlen可能溢出。。。您不能保证未初始化的字符设置为0。

根据strlen描述:

size_t strlen(const char *str);

返回给定以null结尾的字节字符串的长度,即str指向其第一个元素的字符数组中的字符数,最多不包括第一个null字符。如果str不是指向以null结尾的字节字符串的指针,则行为未定义。

由于在第二个版本中,a不是以null结尾的字节字符串,因此行为未定义。

请注意,将单个字符文字分配给char数组并不会使其成为字符串文字,要使用这种分配创建一个以null结尾的char数组,您需要自己完成,从索引0:开始

a[0] = 'a';
//...
a[3] = '';

最新更新