字符串末尾的空字符“\0”

A null character '\0' at the end of a string

我有以下代码。

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

#define MAXLINE 1000

int main()
{
    int i;
    char s[MAXLINE];

    for (i = 0; i < 20; ++i) {
        s[i] = i + 'A';
        printf("%c", s[i]);
    }

    printf("\nstrlen = %d\n", strlen(s)); // strlen(s): 20
    return 0;
}

我应该写

s[i] = '[=11=]';

在循环执行后显式标记字符串结束还是自动完成?没有 s[i] = '[=12=]'; 函数 strlen(s) returns 正确值 20.

是的,您需要自己添加一个空终止符。不会自动添加一个。

您可以通过将 s 显式初始化为在字节 20 处不包含 NUL 的内容来验证这一点。

char s[MAXLINE] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

如果你这样做 strlen(s) 就不会 return 20.

是的,您应该在循环后添加空终止符。或者,您可以使用 0 初始化整个数组。这样,您就不必在循环后添加 0,因为已经有一个:

...
char s[MAXLINE] = {0};
...

您必须添加一个 NUL 终止符来标记 C 字符串的结尾。

添加 NUL 终止符不是自动的(除非文档说明函数调用会为您写入 NUL 终止符)。

在你的情况下,使用:

s[20] = 0;

如评论中所述,C 字符串由终止符 NUL 字符定义。所有 strXXX C 函数也需要 NUL 字符。

如果您不使用 NUL 标记字符串的结尾,则您有一个(二进制)字符序列,但不是 C 字符串。这些有时被称为二进制字符串,它们不能使用strXXX库函数。

为什么你得到正确的结果

很可能您得到正确的结果大部分是偶然的。

对正确结果最可能的解释是 您使用的 OS 为您提供了 "clean" 内存堆栈(初始堆栈内存全为零)... 情况并非总是如此

由于您在执行代码之前从未写入堆栈内存,因此以下字节是之前的字节(在您的 OS 上,该字节在堆栈首次初始化时设置为零)。

但是,如果 OS 没有 为您提供 "clean" 堆栈,或者如果您的代码运行在以前使用的堆叠.