C语言中的字符数组和字符串终止字符
我知道在C中,C语言中的字符数组和字符串终止字符,c,arrays,string,printf,C,Arrays,String,Printf,我知道在C中,\0终止字符串。 我们可以将字符串和字符数组都分配给字符数组 char c1[] = "hello"; char c2[] = {'h','e','l','l','o'}; 但是,我知道字符数组没有\0作为终止字符: printf("%d\n",sizeof(c1)); //6 printf("%d\n",sizeof(c2)); //5 但是,当我打印它们时,我会看到如下内容: printf("%s\n",c1); //hello printf("%s\n",c2); /
\0
终止字符串。
我们可以将字符串和字符数组都分配给字符数组
char c1[] = "hello";
char c2[] = {'h','e','l','l','o'};
但是,我知道字符数组没有\0
作为终止字符:
printf("%d\n",sizeof(c1)); //6
printf("%d\n",sizeof(c2)); //5
但是,当我打印它们时,我会看到如下内容:
printf("%s\n",c1); //hello
printf("%s\n",c2); //helloV
问题1。如果我重新运行它,第二行有时打印helloU
,有时打印helloV
。为什么会这样
问题2。另外,字符数组可以包含终止字符串\0
,也可以不包含终止字符数组\0
char c1[] = "hello";
char c2[] = {'h','e','l','l','o'};
第三季度。我知道printf
遇到\0
时终止。当未遇到\0
时,printf
的行为如何
c2
不是字符串,因此将其传递给printf
%s
具有未定义的行为。未定义的行为是未定义的。从技术上讲,它不需要打印任何内容。它也可以删除你所有的文件或进入无限循环或printf
遇到\0
时停止读取内存。在使用c2
的示例中,您不知道printf
何时停止读取,因为您不知道下一个\0
在内存中的位置printf
确实在读取随机内存,这解释了为什么您无法预测屏幕上会打印什么。最终,您可能会开始读取不属于您的程序的内存。如果发生这种情况,大多数操作系统将立即终止您的程序
想想这个简单的例子:
int a;
printf("%d", a);
您无法预测
a
将包含什么内容,因此无法预测屏幕上将打印什么内容。在您的示例中发生了完全相同的情况,您不知道第二个数组中的'o'
后面是什么。1-未定义的行为;2-ok(因为不是每个字符数组都是字符串);3-未定义的行为#1,未定义的行为。Printf正在寻找尾随的0,它不在那里,它一直在寻找,直到找到一个(#3),但是为什么Printf
只打印helloU
和helloV
,我的意思是为什么只打印U
和V
为什么总是六个字符?为什么不更多?这取决于调试器/操作系统初始化内存的方式。在我的机器上(macOS Mojave,Xcode 10),我得到了hellohello
。这种未定义的行为似乎总是遵循一种“模式”,这一事实并不意味着它不那么未定义。试着运行你的代码,你会得到不同的结果。另外,试着交换c1
和c2
的声明。这将改变数组在内存中的布局方式,也可能会改变输出。但我仍然很好奇为什么printf
只打印helloU
和helloV
,我的意思是为什么只打印U
和V
,为什么总是六个字符?为什么不更多?@anir这取决于平台/编译器的详细信息。您必须查看生成的代码、堆栈布局等。(1)“并非所有字符数组都是字符串。
”如何区分它们?使用\0
终止与不使用\0
终止相比。(2) “只要不将其传递给需要字符串的函数,就可以在字符数组中存储所需的任何内容。
”,您的意思是,如果不将字符数组传递给需要字符串的函数,就可以忘记在其中包含\0
,这样仍然可以吗?