Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我们需要添加一个'\0';(null)在C中字符数组的末尾?_C_Arrays_String_Algorithm_Char - Fatal编程技术网

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

为什么我们需要添加一个'\0';(null)在C中字符数组的末尾?,c,arrays,string,algorithm,char,C,Arrays,String,Algorithm,Char,为什么我们需要在C中的字符数组末尾添加'\0'(null)? 我在K&R2(1.9字符数组)中读过。书中查找最长字符串的代码如下: #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];

为什么我们需要在C中的字符数组末尾添加'\0'(null)? 我在K&R2(1.9字符数组)中读过。书中查找最长字符串的代码如下:

#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;
}
#包括
#定义MAXLINE 1000
int readline(字符行[],int maxline);
无效副本(字符到[],字符从[]);
main(){
内伦;
int max;
字符行[MAXLINE];
字符最长[MAXLINE];
max=0;
而((len=readline(line,MAXLINE))>0)
如果(长度>最大值){
max=len;
副本(最长,行);
}
如果(最大值>0)
printf(“%s”,最长);
返回0;
}
int readline(字符s[],int lim){
int c,i;
对于(i=0;i
我的问题是为什么要将字符数组的最后一个元素设置为“\0”? 没有它,程序运行良好。。。
请帮助我…

您需要用
'\0'
结束C字符串,因为这是库知道字符串结束位置的方式(在您的情况下,
copy()
函数需要这样做)

没有它,程序运行良好


如果没有它,您的程序将无法运行。如果程序恰好做了您期望它做的事情,那么您就是幸运的(或者更确切地说,是不幸的,因为在现实世界中,未定义的行为会选择在最不方便的情况下表现出来).

特别是指向长度未知的字符数组的字符串指针是
NULL
终止符确定字符串长度的唯一方法

关于c中

处空终止的精彩讨论“string”表示以空终止的字符数组。将其与pascal字符串进行比较,pascal字符串表示最多255个字符,前面有一个字节指示字符串的长度(但无需终止)


每个appraoch都有它的优点和缺点。

因为C将字符串定义为以第一个空字符结尾的连续字符序列

基本上,C语言的作者可以选择将字符串定义为字符序列+字符串长度,或者使用魔术标记来分隔字符串的结尾

有关此主题的更多信息,我建议阅读本文:

波尔·亨宁·坎普的《最昂贵的单字节错误》

您实际上已经在这里自己写下了答案:

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

此函数中的循环将继续,直到在中的数组中遇到“\0”。如果没有终止零,循环将继续执行未知数量的步骤,直到遇到零或无效内存区域。

这是字符串终止符号,当遇到此符号时,编译器会知道字符串已结束

实际上,您不需要在\0之前结束字符数组。字符串的char*或C表示形式需要以其结尾

对于数组,如果要将其传输到字符串(按char*重新输入),则必须在其结尾后添加一个\0


另一方面,如果要将其作为char*地址并计划在其上使用char*函数,则需要将\0放在数组的末尾。

'\0'
在数组中表示字符串的结尾,这意味着此字符后面的任何字符都不被视为字符串的一部分。这并不意味着它们不是字符数组的一部分。i、 例如,我们仍然可以通过索引来访问这些字符,但当我们调用这个字符数组中与字符串相关的内容时,它们并不是其中的一部分


要使字符串具有正确的格式并能够正确使用字符串函数,它必须是以null结尾的字符数组。如果没有NULL,当我们调用字符数组上的字符串函数时,程序将显示未定义的行为。尽管我们可能在大多数情况下幸运地得到了结果,但这仍然是一个未定义的行为。

\0
表示字符串的结尾局部变量未在C中初始化。因此,局部变量
在没有写入它的地方有垃圾。如果垃圾恰好是
0
,那么您的程序将在不显式写入null的情况下工作。但是,如果在
变量中执行另一个
读取行
,并使这一行比第一行短,您将在
中的第二行末尾看到第一行的剩余部分。在结尾处写入空字符可以防止出现这种情况。@SandyLee\u user53167这次你很幸运:)@SandyLee\u user53167代码中的
copy
函数会一直运行,直到它看到
\0
字符。不,绝对不会。你会导致不确定的行为。在这个简单的例子中,它可能会起作用,但这纯粹是运气。在不同的操作系统或编译器上,或者如果你正在做一些更复杂的事情,比如复制字符串,你会导致内存涂鸦——写在不应该写的部分内存上。尝试在定义
longest
(例如
char x='Z';
)前后添加一些类似于定义字符变量的内容,看看您的程序是否仍能达到预期效果。注意:与此同时,流行的(或多或少)语言Delphi引入了各种类型的字符串,其中只有一种字符串具有255个字符的限制。所有其他的(ansi、unicode、wide等)都有(我认为)4GB的限制。@alzaimar嗯,现在肯定比pascal本身更受欢迎。我自己也不知道。无论哪种方式,程序员都可以选择他或她的毒药,这总是好的。编译器与此无关。它仅在运行时进行计算。