下面这段代码的运行结果是什么?
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("HAHA\n");
}
return 0;
}
创建了一个 int 类型的 arr 数组,数组大小 10,i 从 0 — 12 给数组初始化为 0,每初始化一次打印 HAHA 一次,结果是什么?
如果是 10 个HAHA 那就错!12 个也不对!!
首先数组越界了是肯定的!但是 i = 12 停下来打印 12个 HAHA 怎么也不对?
编译显示错误如下图:
运行截图:
可以看到运行之后光标一直在闪,说明一直在打印HAHA!!!所以代码是死循环!
那为什么是死循环呢?那就调试看一下!调试方法在前两篇的博客里,不会调试可以看一下之前的博客。
可以看到数组元素已经放好了,我们也把 arr[10]、arr[11]、arr[12] 也查看一下!
先忽略 &i 、&arr[12]
注意下面的视频,当 i = 9 初始化完数组后,越界访问初始化了 arr[10]、arr[11]、arr[12]。
但是!!!
注意看 &i(i 的地址)和 &arr[12] (arr[12] 的地址)是不是发现地址一样!!!
并且 i 的值与 arr[12] 的值也一样,i 的值怎么变 arr[12] 也怎么变!
原因是什么呢? 这里就涉及关于内存的存储了!!
那么这些创建的值在内存中是怎么存储的呢?
内存分几个区分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。但是我不把这几个区都解释一下,只解释栈区。
这个创建的 i 和 数组 arr 都在栈区存放着,那怎么存着呢?
如下图:
i 初始化数组,当 i 越界访问下标为 10 的位置的话,理论上就是在下标为 9 的下一个,那下标 11 也是如此。下标为 12 也是如次!!!
但是程序先创建了 i ,根据栈区使用高地址的规则,i 相对于数组 arr 在栈区的地址更高一些!
但数组随着下标的增加,地址由低到高。
所以栈区内 i 和 arr[12] 的位置重复,当 i 越界访问下标 12 ,也就访问到了最开始创建的 i 的位置,然后访问并且初始化为 0 ,i 也就为 0 了,程序 for 判断条件成立又开始执行打印,所以是死循环!
如果不要程序死循环的话,根据栈区的使用规则,可以先创建数组,再创建 i 。
虽然不会死循环,但是程序本来就越界访问了,也有错误。