为什么/何时在C字符串中包含终止符'\ 0'? [英] Why/when to include terminating '\0' character for C Strings?

查看:454
本文介绍了为什么/何时在C字符串中包含终止符'\ 0'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C还是很陌生,对于何时需要在字符串中手动添加终止的'\ 0'字符感到有些困惑.给定此函数来计算字符串长度(为清楚起见):

I'm very new to C and am a bit confused as to when we need to manually add the terminating '\0' character to strings. Given this function to calculate string length (for clarity's sake):

int stringLength(char string[])
{
    int i = 0;
    while (string[i] != '\0') {
        i++;
}
    return i;
}

根据空终止符计算字符串的长度.那么,在以下情况下,'\ 0'字符(如果有)的作用是什么?

which calculates the string's length based on the null terminating character. So, using the following cases, what is the role of the '\0' character, if any?

情况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

(这些结果每次都不同,但永远不会正确).

(These results vary each time, but are never correct).

情况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中没有足够的内存来分配空终止字符(因为松弛"中的每个字母都只分配了5个字符槽,如何检测"\ 0"字符,即第6个字符?)

Namely, I would like to know the difference between cases 1, 2, 3, and 4 (also why the erratic behavior of case 2 and no need to specify the null-terminating character in 1 and 3. Also, how 3 and 4 both work the same?) and how 5 and 6 print out the same thing even though not enough memory is allocated in case 5 for the null-terminating character (since only 5 char slots are allocated for each letter in "slack", how does it detect a '\0' character, i.e. the 6th character?)

对于这个荒唐冗长的问题,我感到非常抱歉,只是我在其他任何地方都找不到关于这些特定实例的好的教学解释

I'm so sorry for this absurdly long question, it's just I couldn't find a good didactic explanation on these specific instances anywhere else

推荐答案

在情况1中,您正在创建一个字符串常量(将位于只读内存中的常量),该常量将隐式添加了\0.

In case 1, you are creating a string literal (a constant which will be on read only memory) which will have the \0 implicitly added to it.

由于依靠\0的位置来查找字符串的结尾,因此您的stringLength()函数将打印5.

Since \0's position is relied upon to find the end of string, your stringLength() function prints 5.

在情况2中,您尝试使用5个字符的字符串初始化大小为5的字符数组,而\0分隔符不留空格.字符串附近的内存可以是任何内容,并且在某处可能有\0.在这里,此\0被认为是字符串的结尾,它解释了您得到的那些怪异字符.看来,对于您给出的输出,仅在另外3个字符之后才发现了此\0,这在计算字符串长度时也已考虑在内.由于内存的内容会随时间变化,因此输出可能并不总是相同.

In case 2, you are trying to initialise a character array of size 5 with a string of 5 characters leaving no space for the \0 delimiter. The memory adjacent to the string can be anything and might have a \0 somewhere. This \0 is considered the end of string here which explains those weird characters that you get. It seems that for the output you gave, this \0 was found only after 3 more characters which were also taken into account while calculating the string length. Since the contents of the memory change over time, the output may not always be the same.

在情况3中,您正在使用大小为5的字符串初始化大小为6的字符数组,并留有足够的空间来存储将隐式存储的\0.因此,它将正常工作.

In case 3, you are initialising a character array of size 6 with a string of size 5 leaving enough space to store the \0 which will be implicitly stored. Hence, it will work properly.

情况4与情况3相似.

char stack4[5] = '\0';

因为stack4的大小是6,因此它的最后一个索引是5.您正在用其旧值本身覆盖一个变量. stack4[5]甚至在您改写之前就已经包含了\0.

because size of stack4 is 6 and hence its last index is 5. You are overwriting a variable with its old value itself. stack4[5] had \0 in it even before you overwrote it.

在情况5中,您已经用字符完全填充了字符数组,而没有为\0留空格.但是,当您打印字符串时,它会正确打印.我认为这是因为与malloc()分配的内存相邻的内存只是碰巧为零,这是\0的值.但这是未定义的行为,因此不应依赖.实际发生的情况取决于实现方式.
应该注意的是,与calloc()不同,malloc()不会初始化它分配的内存.

In case 5, you have completely filled the character array with characters without leaving space for \0. Yet when you print the string, it prints right. I think it is because the memory adjacent to the memory allocated by malloc() merely happened to be zero which is the value of \0. But this is undefined behavior and should not be relied upon. What really happens depends on the implementation.
It should be noted that malloc() will not initialise the memory that it allocates unlike calloc().

两者

char str[2]='\0';

char str[2]=0;

是一样的.

但是您不能依靠它为零.由于操作系统的工作以及出于安全原因,动态分配的内存的默认值可能为零.请参见此处和<有关详细信息,请参见a href ="https://stackoverflow.com/questions/17444525/what-is-the-default-value-after-malloc-in-c">此处.

But you cannot rely upon it being zero. Memory allocated dynamically could be having zero as the default value owing to the working of the operating system and for security reasons. See here and here for more about this.

如果需要将动态分配的内存的默认值设置为零,则可以使用calloc().

If you need the default value of dynamically allocated memory to be zero, you can use calloc().

案例6的末尾带有\0,其他位置带有字符.在打印时应显示正确的字符串.

Case 6 has the \0 in the end and characters in the other positions. The proper string should be displayed when you print it.

这篇关于为什么/何时在C字符串中包含终止符'\ 0'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆