不同声明方式下无终止空字符的C字符串输出差异原因探究
'\0'的字符串在不同声明下的输出差异原因 核心原因是**puts()依赖'\0'终止符来停止输出,没有终止符时会越界访问内存(属于未定义行为)**,而三种声明方式的内存布局或语义完全不同,导致表现有差异:
情况1:
char a[]={'a','b','c','d'}
这个数组的长度被自动推导为4,刚好容纳4个字符,数组末尾没有多余空间。puts()从数组起始地址开始输出,读完4个字符后会继续读取数组后面的栈内存(这部分是未定义的垃圾数据),直到偶然遇到某个'\0'才停止。你看到的abcd<就是数组内容加上后面的随机垃圾字符,最后的空行是puts()自带的换行。情况2:
char a[100]={'a','b','c','d'}
数组长度显式声明为100,C标准规定:如果数组只初始化了部分元素,剩余未初始化的元素会被自动初始化为'\0'(也就是空字符)。所以a[4]到a[99]全是'\0',puts()读到第4个字符后,下一个就是'\0',自然停止输出,只会打印abcd,再加上puts()自带的换行。情况3:
char *a={'a','b','c','d'}
这是语法错误的声明:char*是指针类型,初始化时需要赋予一个内存地址,而你用了多元素的初始化列表。编译器处理这种错误时,通常会只取列表的第一个值'a'(ASCII值为97)作为指针的地址,也就是让a指向内存地址0x61(十进制97)——这个地址属于系统保留的无效内存区域,puts()访问这个地址时要么直接触发内存错误,要么读不到任何有效字符,所以最终只输出puts()自带的空行(甚至程序可能崩溃)。
内容的提问来源于stack exchange,提问作者Asigan

