设定为全局变量的字符串数组,为什么在主函数内可以设定超过大小的容量(语言-c++)

问题遇到的现象和发生背景

char s[10]设定为全局变量,在主函数内可以输入超过10位的数,并输出
但将char s[10]放入主函数内部,就无法输入超过10位的数

问题相关代码,请勿粘贴截图

char s[10];
int main()
{
int i=0;
//char s[10]; //放入内部
cin>>s;
while(s[i]){
cout<<s[i];
i++;
}
return 0;
}

运行结果及报错内容

放入外部
13234655524497812
13234655524497812
放入内部
13234655524497812

我的解答思路和尝试过的方法
我想要达到的结果

字符串的结束标志'\0',你定义成全局变量,是有默认值0的,所以字符串即使越界了有结束标识符。也可以正常输出。
当你定义在函数内部时,是随机值。这样越界了的话很有可能访问到别的数据地址,就没有结束标识符,所以就没法输出字符串。

具体的你可以去了解一下堆空间和栈空间

其实,无论是全局或者局部,都可以输入超过声明长度的char字符串,但是都会造成不可测的结果。

对于变量而言,只有你声明了那部分内存,才会存储属于自己的内容。不过,C/C++却不会取去检查这种情况,假如一个数组,你声明的长度为10,输入了长度为11的内容,并不会报错,多出来的会继续写入下一个内存空间。

char s[10],定义了一个10个字符数组,在内存空间里,10个字符后也是有内存的,只是你不能控制操作


while(s[i]){
cout<<s[i];
i++;
}

while 是判断为0跳出循环,你如果输入超过10个不为0的值,数组越界了

不管是放在外部还是内部,最好都不要超过长度,先说是不是可不可以,最重要是不满足开发规范,让人很难理解

c语言中的数组变量的名字有两个含义,一个是作为标记数组的唯一性,比如你不能在同一段代码内再次以同一个名字来命名另外一个变量;另一个就是它存储的是数组内存位置的首地址;

所以当你将一段大于数组长度的数据往该数组中写入的时候,实际上是以首地址开始依次写入,由于c语言没有显式的越界检查,除非你写入到一块不可写的内存中,c语言才会报错;

而在访问的这个数组内容的时候,比如你以%s,去打印一个char str[10] = "12345678901234"的时候,%s的打印规则是从首地址开始,直到遇见'\0'停止,所以能够打印出"12345678901234",因为以char str[10] = "12345678901234"这种方式为一个数组进行初始化的时候末尾是自动加'\0'的。

所以在对数组进行初始化或者赋值的时候,最好是使用带有长度参数的拷贝函数或者自己去做赋值长度的限定,不然容易在写的时候出问题。并且,有可能你越界的数据结尾的'\0'有可能被其他代码或者程序擦除,这个时候读出来的数据就变成非可控的了。

这是成员变量和局部变量的区别