C中字符串末尾的两个空终止符

Two null termination signs at the end of a string in C

我正在通过 "The C Programming Language" 书学习 C。在其中一个需要连接两个字符串的练习中,我发现在结果字符串的末尾有两个空终止符 (\0)。这正常吗?

函数代码:

void
copy_str_to_end(char *target, char *destination)
{
        while (*destination != '[=10=]')
                ++destination;
        while ((*destination++ = *target++) != '[=10=]')
                ;
}

输出: This is a destination. This is a target.这里好像一切都OK,但是如果我运行这个函数要测试:

void
prcesc(char *arr)
{
        int i;

        for (i = 0; i <= strlen(arr) + 1; i++)
                if (arr[i] != '[=11=]')
                        printf("%c", arr[i]);
                else
                        printf("E");
        printf("\n");
}

问题变得可见:This is a destination. This is a target.EE (E 表示 \0) 那么,我应该担心这个吗?如果是,这件事发生的原因是什么?

输出中的额外 E 是因为您也是 运行 prcesc 函数中的 while 循环 for i = strlen(arr) + 1。 strlen returns 字符串的长度说 'n'。所以 arr[n-1] 是字符串的最后一个元素,并且 arr[n] 中的所有元素都是 '\0'。 因此,当您对 arr[n]、arr[n+1] 进行迭代时,您会得到两个空字符。

以下功能是您所需要的:

void
prcesc(char *arr)
{
    int i;

    for (i = 0; i <= strlen(arr); i++)
            if (arr[i] != '[=10=]')
                    printf("%c", arr[i]);
            else
                    printf("E");
    printf("\n");
}

问题基本上是由于在 for 循环条件中使用 <= 运算符而不是 < 运算符引起的:

i <= strlen(arr) + 1

strlen(arr) + 1 给出数组中元素的数量,arr 指向调用者(实际上包含字符串)。

当您使用 i <= strlen(arr) + 1 时,循环比预期多迭代一次,并且您尝试在最后一次使用

的迭代中访问超出数组边界的元素
if (arr[i] != '[=11=]')

因为索引计数从 0 开始,而不是 1

要访问超出数组边界的内存,调用 undefined behavior