所以我正在学习使用编译器 Dev C++ 编写 C 语言程序。 问题一:
#include <stdio.h>
#include <conio.h> //for the getch() function
#include <string.h>
int main(void)
{
char line[3];
strcpy(line, "Hello world");
printf("%s", line);
getch();
}
输出: 世界,你好
为什么当我声明我的字符串只包含 3 个字符时它显示所有的“Hello world”?
问题二:
char line[3] = "Hello world";
printf("%s", line);
输出: 帮助
为什么会显示“Hel”?由于 line[0] = H、line[1] = e 和 line[2] = '\0',它不应该只显示“He”吗? %s 是通过搜索 '\0' 来工作的吗?
请帮助我了解实际情况。谢谢!
最佳答案
Please help me understand whats really happening.
未定义的行为!
当你这样做时,你有一个 buffer overrun :
char line[3];
strcpy(line, "Hello world");
Why is it that it displays all of "Hello world" when i declared my string to only hold 3 characters?
您正在复制超过分配数组的大小。这是未定义的行为,因此任何输出都是可能的,包括但不限于调用蒂尔达阿姨、格式化硬盘等:) See here了解更多。
char line[3] = "Hello world";
printf("%s", line);
这是一个 buffer over-read !引用alk's answer关于为什么只有 3 个字符会被复制到 line
。
Why is it that it displays "Hel"? Shouldnt it display only "He"
不,它可以显示任何东西,同样是因为未定义的行为。查看我在我的机器上得到的输出:
Hel☻
这是未定义的行为,因为 printf
期望您有一个以 null 结尾的字符串,是的,但这并不意味着您可以访问超出数组大小的内容,即您有一个数组内存中的这个
[0] [1] [2] ----------------------------------------------- . . . █ | █ | █ | H | e | l | █ | █ | █ | . . . ----------------------------------------------- <-- line --->
上面写为 █ 的任何东西都是未知值,不在你的权力之下,因此访问它们是未定义的。但是,printf
中的 %s
需要一个以 null 结尾的字符串,因此,根据您的命令,它读取的内容超出了允许的范围(允许的只有三个元素,直到 l
).在我的例子中 \0
出现在 l
(笑脸)之后的一个元素,而在你的例子中它就在 l
之后因此看起来正确但只有运气好的话,1000个元素以后可能会出现。
如果您真的想打印 char
数组,它不是以 null 结尾的,并且只打印到允许的限制,您可以执行其中之一而不会遇到任何未定义的行为。
printf("%.3s", line); // length specified at compile-time
printf("%.*s", 3, line); // length fed at run-time
See here了解更多信息。
关于C编程中对字符串的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25094299/