简体   繁体   English

为什么我们需要在C中的字符数组末尾添加一个'\0'(null)?

[英]Why do we need to add a '\0' (null) at the end of a character array in C?

Why do we need to add a '\0' (null) at the end of a character array in C?为什么我们需要在C中的字符数组末尾添加一个'\0'(null)? I've read it in K&R 2 (1.9 Character Array).我在 K&R 2(1.9 字符数组)中读过它。 The code in the book to find the longest string is as follows:书中求最长字符串的代码如下:

#include <stdio.h>
#define MAXLINE 1000
int readline(char line[], int maxline);
void copy(char to[], char from[]);

main() {
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];
    max = 0;
    while ((len = readline(line, MAXLINE)) > 0)
        if (len > max) {
            max = len;
            copy(longest, line);
        }
    if (max > 0)
        printf("%s", longest);
    return 0;
}

int readline(char s[],int lim) {
    int c, i;
    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0'; //WHY DO WE DO THIS???
    return i;
}

void copy(char to[], char from[]) {
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

My Question is why do we set the last element of the character array as '\0'?我的问题是为什么我们将字符数组的最后一个元素设置为'\0'? The program works fine without it... Please help me...没有它,程序也能正常工作……请帮帮我……

You need to end C strings with '\\0' since this is how the library knows where the string ends (and, in your case, this is what the copy() function expects). 您需要使用'\\0'结束C字符串,因为这是库知道字符串结束的位置(在您的情况下,这是copy()函数所期望的)。

The program works fine without it... 没有它,该程序工作正常......

Without it, your program has undefined behaviour . 没有它,您的程序具有未定义的行为 If the program happens to do what you expect it to do, you are just lucky (or, rather, unlucky since in the real world the undefined behaviour will choose to manifest itself in the most inconvenient circumstances). 如果程序碰巧做了你期望它做的事情,你就是幸运的(或者说,不幸的是,因为在现实世界中未定义的行为将选择在最不方便的情况下表现出来)。

Especially string pointers pointed to array of characters without length known is the only way NULL terminator will determine the length of the string. 特别是字符串指针指向没有长度已知的字符数组是NULL终止符将确定字符串长度的唯一方法。

Awesome discussion about NULL termination at link 关于链接上的 NULL终止的讨论很棒

In c "string" means a null terminated array of characters. 在c“string”中表示以null结尾的字符数组。 Compare this with a pascal string which means at most 255 charactes preceeded by a byte indicating the length of the string (but requiring no termination). 将其与pascal字符串进行比较,这意味着最多255个字符,前面是一个字节,表示字符串的长度(但不需要终止)。

Each appraoch has it's pros and cons. 每个appraoch都有它的优点和缺点。

Because C defines a string as contiguous sequence of characters terminated by and including the first null character . 因为C将字符串定义为由第一个空字符终止并包括第一个空字符的连续字符序列

Basically the authors of C had the choice to define a string as a sequence of characters + the length of string or to use a magic marker to delimit the end of the string. 基本上,C的作者可以选择将字符串定义为字符序列+字符串的长度,或者使用魔术标记来分隔字符串的结尾。

For more information on the subject I suggest to read this article: 有关该主题的更多信息,我建议您阅读本文:

"The Most Expensive One-byte Mistake" by Poul-Henning Kamp http://queue.acm.org/detail.cfm?id=2010365 Poul-Henning Kamp 撰写的 “最昂贵的单字节错误” http://queue.acm.org/detail.cfm?id=2010365

You have actually written the answer yourself right here: 你实际上已经在这里自己写了答案:

void copy(char to[], char from[]) {
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

The loop in this function will continue until it encounters a '\\0' in the array from . 在这个函数中的循环将继续,直到它该阵列中遇到“\\ 0”。 Without a terminating zero the loop will continure an unknown number of steps, until it encounters a zero or an invalid memory region. 如果没有终止零,则循环将继续执行未知数量的步骤,直到遇到零或无效的存储区域。

Really, you do not need to end a character array by \\0. 真的,你不需要通过\\ 0结束的字符数组。 It is the char*, or the C representation of the string that needs to be ended by it. 它是char *,或者需要由它结束的字符串的C表示。

As for array, you have to add a \\0 after its end if you want to transfer it to the string (representer by char*). 对于数组,如果要将其传递给字符串(由char *表示,则必须在结束添加\\ 0)。

On the other hand, you need to have \\0 at the end of the array, if you want to address it as char* and plan to use char* functions on it. 另一方面,如果要将其作为char *进行处理并计划在其上使用char *函数,则需要在数组末尾使用\\ 0。

'\\0' in the array indicates the end of string, which means any character after this character is not considered part of the string.It doesn't mean they are not part of the character array. 数组中的'\\0'表示字符串的结尾,这意味着该字符后面的任何字符都不被视为字符串的一部分。这并不意味着它们不是字符数组的一部分。 ie, we can still access these characters by indexing but they are just not part when we invoke string related things to this character array. 也就是说,我们仍然可以通过索引来访问这些字符,但是当我们向这个字符数组调用与字符串相关的东西时它们就不合适了。

For a string to be in proper format and be able to work properly with the string functions, it must be a null-terminated character array. 要使字符串格式正确并且能够与字符串函数一起正常工作,它必须是以null结尾的字符数组。 Without NULL, the programs show undefined behavior when we invoke string functions on the character array. 如果没有NULL,当我们在字符数组上调用字符串函数时,程序会显示未定义的行为。 Even though we might get lucky with the results most of the times, it still is an undefined behavior. 尽管我们大多数时候都可能对结果感到幸运,但它仍然是一种未定义的行为。

I've just looked it up If your array is considered as string Which means like this char array[MAX]="string";我刚刚查了一下如果你的数组被认为是字符串这意味着像这样的char array[MAX]="string"; Or like this scanf("%s",array);或者像这样scanf("%s",array); Or char* table;或者char* table; Then the NULL character '\0' will append automatically as the end of the characters on that table But if you initialized it like this char array[MAX]={'n','o','t','s','t,'r'};然后 NULL 字符'\0'将自动作为该表上字符的末尾 append 但是如果你像这样初始化它char array[MAX]={'n','o','t','s','t,'r'}; Or you fill it using character by character with %c format或者您使用%c格式逐个字符地填充它

for(int i=0;i<MAX;i++)
   scanf("%c",&array[i]);

Or getchar() instead of scanf("%c",...) Then you have to add '\0' by yourself Because now it considered as any other array's type (int,float...) So the cases that we consider as empty are actually filled by random numbers or characters depends on the type Meanwhile in the case of a string type the next character after the last considered character is by default '\0' for more explanation the length of this char array[]="12345" is 6 The array[5]=='\0' will return 1 by other words you can't define a string array like this char array[3]="123" because we left no room for the '\0' that has to append automatically last example char array[7]={'t','e','s','t','\0'};或者getchar()而不是scanf("%c",...)然后你必须自己添加'\0'因为现在它被认为是任何其他数组的类型 (int,float...) 所以我们的情况考虑为空实际上由随机数或字符填充取决于类型同时在字符串类型的情况下,最后一个考虑的字符之后的下一个字符默认为'\0'以获得更多解释这个char array[]="12345"是 6 array[5]=='\0'将返回 1 换句话说你不能像这样定义一个字符串数组char array[3]="123"因为我们没有为'\0'必须自动最后一个例子 append char array[7]={'t','e','s','t','\0'}; Here array[4] is the NULL character array[5] and array[6] are random values But if it was string then "test" array[4] and 5 and 6 are all filled by the NULL character (NULL character can refers to any white_space as I think so tab '\t' and enter '\n' are also NULL characters just like '\0' which may refer to spacebar) nota ben: we can't assign array[7] or more as we all know but if you try to output it, it'll show a random value as any empty case这里array[4]是NULL字符array[5]和array[6]是随机值但是如果是string那么"test"array[4]和5和6都是由NULL字符填充的(NULL字符可以参考到我认为的任何 white_space 选项卡'\t'并输入'\n'也是 NULL 个字符,就像'\0'可能指的是空格键)注意本:我们不能分配数组 [7] 或更多,因为我们都知道但是如果你尝试 output 它,它会显示一个随机值作为任何空的情况

它是字符串终止符号,当遇到这种情况时,编译器会知道你的字符串已经结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM