为什么使用太长的初始化程序初始化的字符串会表现得像这样

Jin*_*oss 3 c string pointers

#include<stdio.h>

void main()
{
    int i;
    char str[4] = "f4dfkjfj";
    char str2[3] = "987";
    char str3[2] = {'j','j','\0'};

    //printf("%c\n",str[1]);
    //printf("%c\n",1[str]);

    puts(str);
    puts(str2);
    puts(str3);           
}
Run Code Online (Sandbox Code Playgroud)

产出观察:

  • 打印str2打印无论从内容str2和str.
  • 打印str3打印件str3,str2和str.

为什么这个行为在打印非nul时结束了字符串,它与先前定义的字符串连接,直到puts()函数遇到"\ 0"字符(此函数打印直到遇到nul)?

(注意:我故意用太长的初始化字符串初始化它们)

Sou*_*osh 5

(注意:我故意用太长的初始化字符串初始化它们)

那么你也应该意识到副作用.

所有数组的问题是,它们不是以空值终止的,因此它们不是 字符串.

引用C11,章节§7.1.1,术语定义,(强调我的)

甲串是字符的连续序列通过终止并且包括第一个空字符.[...]

将它们与字符串处理函数(例如puts())一起使用将调用未定义的行为,因为搜索空终止符的函数将超出绑定(即,允许的外部存储区域)并导致无效的内存访问.

再次引用标准,第7.21.7.9章,

该puts函数将指向s的字符串写入指向的流stdout,并将新行字符附加到输出.不写入终止空字符.

期望的参数是一个字符串,代码中没有任何参数.

这就是说,FWIW,对于托管环境,推荐的签名main()是int main(void),至少.