我现在正在学习C,而且我真的没有得到用NULL '\0'
字符初始化字符串结尾的区别。以下是本书的例子:
#include <stdio.h>
#include <string.h>
int main(){
int i;
char str1[] = "String to copy";
char str2[20];
for(i = 0; str1[i]; i++)
str2[i] = str1[i];
str2[i] = '\0'; //<====WHY ADDING THIS LINE??
printf("String str2 %s\n\n", str2);
return 0;
}
那么,为什么我要添加NULL字符?因为它也没有那条线。另外,如果我使用以下是否有区别:
for (i = 0; str1[i]; i++){
str2[i] = str1[i];
}
感谢您的时间。
答案 0 :(得分:2)
您所指的行是为了安全而添加的。当您将值复制到字符串时,您总是希望确保它是空终止的,否则在读取字符串时它将继续超过您希望该字符串结束的点(因为它不知道应该在哪里停止到期缺少空终止符。)
与您发布的备用代码没有区别,因为您只将for语句下面的行分隔为循环,如果您不使用花括号{}
,默认情况下会发生这种情况。答案 1 :(得分:1)
在C中,字符串的结尾由空字符检测。考虑字符串'abcd'。如果实际二进制文件中的变量在“d”字符后面紧跟下一个变量,则C会认为平台中的下一个字符是该字符串的一部分,您将继续。这称为缓冲区溢出。
你的初始语句允许str2的20个字节通常用20个零填充它,但是,这不是必需的,可能不会发生。另外,我们假设您将15个字符的字符串移动到str2中。因为它以20个零开始,所以这将起作用。但是,假设您将10个字符的字符串复制到str2中。其余5个字符将保持不变,然后您将拥有一个由新的10个字符组成的15个字符的字符串,后跟之前复制的5个字符。
在上面的代码中,for循环表示将str1中的字符移动到str2并指向下一个字符。如果str1中现在指向的字符不为0,则循环返回并再次执行。否则退出循环。现在将空字符添加到str2的末尾。如果你把它遗漏了,str1末尾的空字符将不会被复制到str2,并且你在str2的末尾没有空字符。
这可以表示为
i = 0;
label:
if (str1[i] == 0) goto end;
str2[i] = str1[i];
i = i + 1;
goto label;
end: /* This is the end of the loop*/
请注意,'\ 0'字符尚未移至str2。
由于C需要括号来显示for的范围,因此只有for后面的第一行才是循环的一部分。如果我有本地范围并且在循环之后丢失,你将无法等待退出循环并使其为0.你将不再有一个有效的i指针告诉你在str2中你需要添加的位置0。
一个例子是C ++或C中的一些编译器,它们允许(语法上)
for (int i = 0; str1[i]; i++)
{
str2[i] = str1[i];
}
str2[i] = 0;
这会失败,因为我会被重置为它进入循环之前发生的任何事情(可能是0),因为它不在循环中。如果在循环之前尚未定义它,则会得到未定义的变量编译器错误。
我看到您修复了缩进,但原始缩进仍然存在,以下注释将适用。
C不仅仅通过缩进工作(例如,Python)。如果是这样,逻辑将如下,它将失败,因为str2将被覆盖为全0。
for (int i = 0; str1[i]; i++)
{
str2[i] = str1[i];
str2[i] = 0;
}
答案 2 :(得分:0)
'\ 0'用于表示字符串结尾。它不适用于编译器,它适用于库以及可能的代码。 C不能正确支持数组。您可以拥有本地数组,但无法传递它们。如果您尝试只传递起始地址(第一个元素的地址)。所以你可以让最后一个元素变得特殊,例如'\ 0'或者总是传递大小,注意不要搞砸。
例如:
如果您的字符串是这样的:
char str[]="Hello \0 World";
你会告诉我如果你打印str
会显示什么?
输出是:
Hello
在字符数组中就是这种情况,因此为了更加安全,最好在字符串的末尾加上'\ 0'。
如果你没有添加'\ 0',可能会打印出一些垃圾值,它会继续打印,直到达到'\ 0'
答案 3 :(得分:0)
您应该只在字符串的末尾添加\0
(也称为空字节)。请执行以下操作:
...
for(i = 0; str1[i]; i++) {
str2[i] = str1[i];
}
str2[i] = '\0'; //<====WHY ADDING THIS LINE??
...
(请注意,我只是添加了大括号以使代码更具可读性,之前令人困惑)
对我来说,这更清楚。你之前做的事情基本上是利用了这样一个事实,即在你运行循环以在i
的末尾添加\0
后,你声明的整数str2
仍然可用。 / p>
字符串在C中的工作方式是它们基本上是指向第一个字符位置的指针,字符串函数(例如您在string.h
中可以找到的函数)将读取每个字符,直到它们找到\0
(空字节)。它只是标记字符串结尾的约定。
进一步阅读:http://www.cs.nyu.edu/courses/spring05/V22.0201-001/c_tutorial/classes/String.html
答案 4 :(得分:0)
在C中,char []不知道字符串的长度。因此,重要字符'\ 0'(ASCII 0)表示字符串的结尾。你的“For”命令不会复制'\ 0',所以输出是一个字符串&gt; str2(直到找到'\ 0'最后一站)
尝试:
#include <stdio.h>
#include <string.h>
int main(){
int i;
char str[5] = "1234";
str[4] = '5';
printf("String %s\n\n", str);
return 0;
}