我对C很陌生,对于何时需要手动将终止字符“\0”添加到字符串有点困惑。给定此函数来计算字符串长度(为了清楚起见):
int stringLength(char string[])
{
int i = 0;
while (string[i] != '\0') {
i++;
}
return i;
}
它根据空终止字符计算字符串的长度。那么,在下列情况下,'\0'字符的角色是什么(如果有的话)?
案例1:
char * stack1 = "stack";
printf("WORD %s\n", stack1);
printf("Length %d\n", stringLength(stack1));
印刷品:
WORD stack
Length 5
案例2:
char stack2[5] = "stack";
printf("WORD %s\n", stack2);
printf("Length %d\n", stringLength(stack2));
印刷品:
WORD stack���
Length 8
(这些结果每次都不一样,但永远不会正确)。
案例3:
char stack3[6] = "stack";
printf("WORD %s\n", stack3);
printf("Length %d\n", stringLength(stack3));
印刷品:
WORD stack
Length 5
案例4:
char stack4[6] = "stack";
stack4[5] = '\0';
printf("WORD %s\n", stack4);
printf("Length %d\n", stringLength(stack4));
印刷品:
WORD stack
Length 5
案例5:
char * stack5 = malloc(sizeof(char) * 5);
if (stack5 != NULL) {
stack5[0] = 's';
stack5[1] = 't';
stack5[2] = 'a';
stack5[3] = 'c';
stack5[4] = 'k';
printf("WORD %s\n", stack5);
printf("Length %d\n", stringLength(stack5));
}
free(stack5);
印刷品:
WORD stack
Length 5
案例6:
char * stack6 = malloc(sizeof(char) * 6);
if (stack6 != NULL) {
stack6[0] = 's';
stack6[1] = 't';
stack6[2] = 'a';
stack6[3] = 'c';
stack6[4] = 'k';
stack6[5] = '\0';
printf("WORD %s\n", stack6);
printf("Length %d\n", stringLength(stack6));
}
free(stack6);
印刷品:
WORD stack
Length 5
也就是说,我想知道情况1、2、3和4之间的区别(也就是为什么情况2的行为不稳定,不需要在1和3中指定空终止字符)。另外,3和4是如何同时工作的?)以及5和6如何打印出相同的内容,即使在第5种情况下没有为空终止字符分配足够的内存(因为在“slack”中每个字母只分配5个字符槽),它如何检测“\0”字符,即第6个字符?)
我很抱歉问了这么长的问题,只是我在别的地方找不到一个很好的解释
最佳答案
在案例1中,您正在创建一个字符串文本(一个将位于只读内存中的常量),它将隐式地将\0
添加到其中。
由于\0
的位置依赖于查找字符串的结尾,因此您的stringLength()
函数将打印5
。
在案例2中,您试图用一个5个字符的字符串初始化一个大小为5的字符数组,该字符串不为\0
分隔符留空格。字符串旁边的内存可以是任何内容,并且可能在某个地方有一个\0
。这里这个\0
被认为是字符串的结尾,它解释了您得到的那些奇怪字符。似乎对于您提供的输出,只有在计算字符串长度时还考虑了3个字符之后,才能找到这个\0
。由于内存的内容随时间而变化,因此输出可能并不总是相同的。
在案例3中,使用大小为5的字符串初始化大小为6的字符数组,留下足够的空间来存储将隐式存储的\0
。因此,它将正常工作。
案例4与案例3相似。不做任何修改
char stack4[5] = '\0';
因为
stack4
的大小是6,所以它的最后一个索引是5。您正在用旧值本身覆盖变量。stack4[5]
甚至在你过度保护它之前就已经在里面了。在案例5中,您已经用字符完全填充了字符数组,而没有为
\0
留出空间。但当你打印字符串时,它就打印对了。我认为这是因为\0
分配的内存旁边的内存恰好是0,这就是malloc()
的值。但这是一种未定义的行为,不应该被依赖。真正发生的事情取决于实现。需要注意的是,与
\0
不同,malloc()
不会初始化它分配的内存。两者
char str[2]='\0';
和
char str[2]=0;
都一样。
但你不能指望它是零。由于操作系统的工作和安全原因,动态分配的内存可能有0作为默认值。有关更多信息,请参见here和here。
如果需要动态分配内存的默认值为零,可以使用
calloc()
。案例6结尾有
calloc()
,其他位置有字符。打印时应显示正确的字符串。关于c - 为什么/何时在C字符串中包含终止符'\0'?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46261028/