何时/为什么'\ 0'需要标记(char)数组的结尾?

时间:2016-11-26 18:04:44

标签: c string null-terminated

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

将空字符\0放在数组的末尾以标记数组的结尾。这有必要吗?

如果我创建了一个char数组:

char line[100]; 

并说出一句话:

"hello\n"

其中,字符将被放置在前六个索引line[0] - line[6]中,因此数组的其余部分将填充空字符吗?

这本书说,这是一个惯例,例如字符串常量"hello\n"放在字符数组中并以\0结尾。

也许我完全不理解这个话题,并且很乐意启蒙。

5 个答案:

答案 0 :(得分:9)

\0字符不标记“数组的结尾”。 \0字符标记存储在char数组中的字符串的结尾, if (仅当)char数组用于存储字符串。< / p>

char数组只是一个char数组。它存储独立的整数值(char只是一个小整数类型)。 char数组不必以\0结尾。 \0在char数组中没有特殊含义。它只是一个零值。

但有时char数组用于存储字符串。字符串是由\0终止的字符序列。因此,如果要将char数组用作字符串,则必须使用\0终止字符串。

因此,关于\0“必要”的问题的答案取决于您在char数组中存储的内容。如果要存储字符串,则必须使用\0终止它。如果您要存储的不是字符串,那么\0根本就没有特殊含义。

答案 1 :(得分:2)

如果您将其用作字符数组,则不需要

'\ 0'。但是如果使用字符数组作为字符串,则需要输入'\ 0'。 C中没有单独的字符串类型。

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

例如:

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

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

答案 2 :(得分:2)

您需要使用空字符标记字符串的结尾。 C不存储有关字符数组长度或字符串长度的任何内部信息,因此空字符/字节\0标记它的结束位置。

这仅适用于字符串,但是 - 您可以拥有任何不代表字符串的普通字符数组。

例如,试试这段代码:

#include <stdio.h>

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

请注意,字符数组完全填充了数据。因此,没有空字节来标记结尾。现在,printf将继续打印,直到它达到空字节 - 这将超过数组的末尾,因此除了“a”之外,您还将打印出大量垃圾。

现在,试试这个:

#include <stdio.h>

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

它只会打印“a”,因为字符串的末尾是明确标记的。

答案 3 :(得分:2)

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

The terminating zero is necessary if a character array contains a string. This allows to find the point where a string ends.

As for your example that as I think looks the following way

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

then for starters the string literal has 7 characters. It is a string and includes the terminating zero. This string literal has type char[7]. You can imagine it like

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

When a string literal is used to initialize a character array then all its characters are used as initializers. So relative to the example the seven characters of the string literal are used to initialize first 7 elements of the array. All other elements of the array that were not initialized by the characters of the string literal will be initialized implicitly by zeroes.

If you want to determine how long is the string stored in a character array you can use the standard C function strlen declared in the header <string.h>. It returns the number of character in an array before the terminating zero.

Consider the following example

#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;
}

Its output is

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

In C you may use a string literal to initialize a character array excluding the terminating zero of the string literal. For example

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

In this case you may not say that the array contains a string because the sequence of symbols stored in the array does not have the terminating zero.

答案 4 :(得分:1)

The length of a C string (an array containing the characters and terminated with a '\0' character) is found by searching for the (first) NUL byte. \0 is zero character. In C it is mostly used to indicate the termination of a character string. I make an example to you:

let's say you've written a word into a file:

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

where in word we allocate space for the 5 character of "Hello" plus one more for its terminating '\0'. The fp is the file. An now, we write another word after the last one:

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

So now, let's read the two words:

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 \0)+(6 characters from 'world!')+(1 character from the \0) */
fread(buff, sizeof(char), 13, fp); // We read the words 'Hello\0' and 'world!\0'
printf("the content of buff is: %s", buff); // This would print 'Hello world!'

This last is due to the ending \0 character, so C knows there are two separated strings into buffer. If we had not put that \0 character at the end of both words, and repeat the same example, the output would be "Helloworld!" This can be used for many string methods and functions!.