代码:
#include<stdio.h>
main(){
char a[6]={'a','b','c','d','e','f'};
printf("%s\n",a);
}
输出结果:
abcdef@
为什么最后有一个@?
还有char b[6]={"abcdef"};这句定义为什么会出错?我把最后一个字符'f'去掉后就正确了,然后输出b结果为:abcde,没有@,为什么,这两种定义有什么不同吗?
那什么第一种定义不会超出而第二种会超出呢?
追答a[6]定义了六个字节的存储空间。
字符串需要有个\0结尾,它本身就占一个字节。那就剩5个字节了。
{'a','b','c','d','e','f'}和{"abcdef"}都是6个字节,而\0就成了第7个字节了。明显超过了变量的定义范围了。
我明白了,第一种初始化只有元素数小于数组长度时才会自动补'\0',而第二种是强制的最后一个字符必定是'\0'。那么问题来了,printf("%s\n",a);是如何判断字符数组结束的呢?最后一个@我还是不明白,他肯定是扫描了的,然后以此作为结束标志(抱歉问的有点多,我提高点悬赏吧,谢谢)
追答printf("%s\n",a),这个%s就说明变量a是字符串。只要是字符串它就应该找\0,只要遇到\0它就不会显示后续的字符了。
你可以用下面的例子看看。
char a[6]={'a','\0','d','f','A','c'};
至于@可能与函数栈结构有关系。具体不清楚。
我不明白的是为什么会输出@(不是随机,今天我又试了几次还是@),char a[6]={'a','b','c','d','e','f'};这种初始化方法没有包含'\0'又是怎样判断输出结束的呢?
追答这就是编译器不同结果也不同。
我的编译器是MinGW GCC
下图是我打得代码和结果:
那什么第一种定义不会超出而第二种会超出呢?
追答因为严格意义上来说,char b[6]是可以定义为{'a','b','c','d','e','f'}的,因为他是字符数组,0-5分别存放a-f,可以通过编译。只是不能再作为字符串%s使用。
而char b[6]={"abcdef"},明确指出为存放字符串"abcdef"于字符数组b中,但是空间不够用,编译器会报错的。