When/Why 是否需要“\0”来标记 (char) 数组的结尾?

When/Why is '\0' necessary to mark end of an (char) array?

所以我刚刚阅读了一个示例,了解如何创建表示字符串的字符数组。

空字符[=13=]放在数组末尾,表示数组结束。这是必要的吗?

如果我创建了一个字符数组:

char line[100]; 

并输入单词:

"hello\n"

其中,字符将被放置在前六个索引 line[0] - line[6],所以数组的其余部分无论如何都会用空字符填充?

这本书说,这是一个约定,例如字符串常量 "hello\n" 放在字符数组中并以 [=13=] 结尾。

也许我没有完全理解这个话题,很高兴得到启发。

'\0' 如果您将其用作字符数组,则不需要。但是如果你使用字符数组作为字符串,你需要放'\0'。 C中没有单独的字符串类型。

有多种声明字符数组的方法。

例如:

char str1[]    = "my string";
char str2[64]  = "my string";
char str3[]    = {'m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', '[=10=]'};
char str4[64]  = {'m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', '[=10=]'};

所有这些数组都有相同的字符串"my string"。在 str1 和 str2 中 '\0' 字符是自动添加的,但在其他两个中,您需要显式添加。

[=10=]字符不标记"end of the array"。 [=10=] 字符标记存储在 char 数组中的 string 的结尾,if(且仅当)该 char 数组是预期的存储字符串。

字符数组就是一个字符数组。它存储独立的整数值(char只是一个小整数类型)。 char 数组不必以 [=10=] 结尾。 [=10=] 在 char 数组中没有特殊含义。它只是一个零值。

但有时使用char数组来存储字符串。字符串是以 [=10=] 结尾的字符序列。因此,如果您想将字符数组 用作字符串 ,则必须使用 [=10=].

终止字符串

因此,关于 [=10=] 是 "necessary" 的问题的答案取决于您在 char 数组中存储的内容。如果要存储 字符串 ,则必须使用 [=10=] 终止它。如果您存储的不是字符串,那么 [=10=] 就没有任何特殊意义。

您需要空字符来标记字符串的结尾。 C 不存储有关字符数组长度或字符串长度的任何内部信息,因此 null character/byte [=12=] 标记它结束的位置。

这仅对 字符串 是必需的,但是 – 您可以使用任何不代表字符串的普通字符数组。

例如,试试这段代码:

#include <stdio.h>

int main(void) {
    char string[1];
    string[0] = 'a';
    printf("%s", string);
}

请注意,字符数组已完全填满数据。因此,没有空字节来标记结束。现在,printf 将继续打印,直到它遇到一个空字节——这将在数组末尾的某个地方,所以除了 "a".[=14 之外,你还会打印出很多垃圾=]

现在,试试这个:

#include <stdio.h>

int main(void) {
    char string[2];
    string[0] = 'a';
    string[1] = '[=11=]';
    printf("%s", string);
}

它只会打印"a",因为字符串的结尾被显式标记了。

通过搜索(第一个)NUL 字节可以找到 C 字符串(包含字符并以 '\0' 字符结尾的数组)的长度。 \0 是零字符。在 C 语言中,它主要用于指示字符串的终止。 我给你举个例子:

假设您已将一个词写入文件:

word = malloc(sizeof(cahr) * 6);
word = "Hello";
fwrite(word, sizeof(char), 6, fp);

word 中,我们为 "Hello" 的第 5 个字符分配 space,再加上一个用于终止 '\0' 的字符。 fp 是文件。 现在,我们在最后一个字之后再写一个字:

word2 = malloc(sizeof(cahr) * 7);
word2 = "world!";
fwrite(word2, sizeof(char), 7, fp);

那么现在,让我们读两个字:

char buff = malloc(sizeof(char)*1000); // See that we can store as much space as we want, it won't change the final result
/* 13 = (5 chacater from 'Hello')+(1 character of the [=12=])+(6 characters from 'world!')+(1 character from the [=12=]) */
fread(buff, sizeof(char), 13, fp); // We read the words 'Hello[=12=]' and 'world![=12=]'
printf("the content of buff is: %s", buff); // This would print 'Hello world!'

这最后一个是由于结尾的 [=15=] 字符,所以 C 知道缓冲区中有两个分隔的字符串。如果我们没有将 [=15=] 字符放在两个单词的末尾,并重复相同的示例,输出将是 "Helloworld!" 这可以用于许多字符串方法和函数!

When/Why is '[=19=]' necessary to mark end of an (char) array?

如果字符数组包含字符串,则终止零是必需的。这允许找到字符串结束的点。

至于你的例子,我认为看起来是这样的

char line[100] = "hello\n";

那么对于初学者来说,字符串文字有 7 个字符。它是一个字符串,包括终止零。此字符串文字的类型为 char[7]。你可以想象成

char no_name[] = { 'h', 'e', 'l', 'l', 'o', '\n', '[=11=]' };

当字符串文字用于初始化字符数组时,它的所有字符都被用作初始值设定项。因此相对于示例,字符串文字的七个字符用于初始化数组的前 7 个元素。未由字符串文字的字符初始化的数组的所有其他元素将由零隐式初始化。

如果要确定字符串存储在字符数组中的长度,可以使用在 header <string.h> 中声明的标准 C 函数 strlen。它 returns 数组中终止零之前的字符数。

考虑以下示例

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

int main(void) 
{
    char line[100] = "hello\n";

    printf( "The size of the array is %zu"
            "\nand the length of the stored string \n%s is %zu\n",
            sizeof( line ), line, strlen( line ) );

    return 0;
}

它的输出是

The size of the array is 100
and the length of the stored string 
hello
 is 6

在 C 中,您可以使用字符串文字来初始化不包括字符串文字的终止零的字符数组。例如

char line[6] = "hello\n";

在这种情况下,您可能不会说数组包含字符串,因为存储在数组中的符号序列没有终止零。