亲爱的读者,大家好!我是一名正在学习编程的高校生。在这个博客里,我将和大家一起探讨编程技巧、分享实用工具,并交流学习心得。希望通过我的博客,你能学到有用的知识,提高自己的技能,成为一名优秀的程序员。如果你有任何疑问或建议,请随时在评论区留言,让我们一起成长进步!现在,让我们开始这场知识之旅吧!
🏞️个人主页: FEN03
📊收入专栏: C语言
🌻🌼🌷🪻🌹🌷🌼🌻🌺🌹🪻🌼🌻🌺🌷🪻🌹🌷🌼🌻🌺🌻🌷🪻🌹🪻🌷🌼🌻🌻🌺🌼🌷🪻🌹🪻🌷
🎄文章目录
- 🦊 前言 🍖
- 🫎 Nice2016年校招笔试题 🥩
- 🦦相同类型题目🥓
- 👋🏻结束语🌹
🦊 前言 🍖
今天,有位朋友给我看了这道题,发现与Nice在2016年校招笔试题中的一道题是类似的,那么就让我们一起来探讨吧~ ⬇️⬇️⬇️
🫎 Nice2016年校招笔试题 🥩
下边代码为Nice在2016年校招笔试题中的其中一道,让我们来一起看看吧😃😃
要求是在LInux X86_64 gcc环境下,下面的程序会出现什么问题?运行结果是什么?为什么?
#include<stdio.h>
int main(int argc, char* argv[])
{
long i;
long a[16];
for (i = 0; i <= 17; i++)
{
a[i] = 0;
printf("%d ", i);
}
return 0;
}
当我看到这一道题目时,我就想起来有一道与它相似的,这道题目最早是出自于《C语言陷阱与缺陷》,那么接下来就让我们一起看看吧~ 🌹
🦦相同类型题目🥓
那么我在VS2022中,X86,Debug的环境下,并且编译器不做任何的优化,下面的代码会执行什么样的结果呢❓❓❓
#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("Nice\n");
}
return 0;
}
运行结果…
我们看到,程序运行结果,是死循环了,那么为什么会这样呢?
让我们调式观察吧⬇️⬇️⬇️
- 我们可以看到已经调式起来,并且可以在监视窗口看到i和arr的值
- 下一步,到了for循环,for遍历数组,把数组的全部下标都改为了0,那么这时候数组还没有越界访问, 但是,for循环并没有到此结束,当我们继续会发生什么呢?
- 当我继续时,这时候已经是越界访问了,并且把arr[10],arr[11],也改成了0,但是这时的for循环还没有结束,那么我再继续会发生什么❓❓❓
- 那么我再继续,也就是最后一次for循环了
看下面动图,我进行最后一次for循环,arr[12]也是改为了0,突然 i 变量变为了0,并且与arr[12]的值是一样的了,这是为什么❓难道它们的地址是一样的吗❓
- 当我把arr[12]与 i 的地址打开看看,可以发现它们的地址是一模一样的。
为了更为详细的解释,我们通过画图的方式进行讲解⬇️⬇️⬇️
分析:
- 首先整型变量i和整型数组arr,它们都是局部变量,那么局部变量是存放在栈区的,而栈区上内存的使用习惯是先使用高地址的空间再使用低地址的空间。
- 那我们知道,栈区是存放局部变量和形式参数;堆区是存放动态内存开辟,如malloc,calloc,realloc,free;静态区是存放全局变量和由static修饰的静态变量。
- 我们可以把上面代码中它们在栈区的内存布局画出来
我们通过该图,可以看到代码在栈区的内存布局,前边我们解释了,栈区是先使用高地址再使用低地址,我们按照创建变量的先后,分别把它们在内存布局画了出来,数组的地址是连续存放的并且是由低地址到高地址,
那么通过不断的遍历数组,当arr[9]改为0时,这时候并没有越界访问,但是遍历还没结束,再次进行,arr[10],arr[11]都被改为了0,这已经是越界访问了,当再一次越界访问,看下图,这时arr[12]访问到了i 。所以,i 与 arr[12] 的地址是相同,既然地址相同,那么它们的值都是一样的,所以当i不断的++,arr[12]的值也跟着++,当arr[12] = 0 时,i也变为了0,最终不断的死循环。那么大家可能会有所疑惑,有这么巧吗❓
- 我们看到 i 和 arr 中间空了2个int,其实这并不是巧合,至于它们中间空多大,取决于编译器的实现,在vc6.0中,相同的代码,i 和 arr 之间没有空隙;在gcc 中,i 和 arr 之间空1个int;在vs中空2个int 。
👋🏻结束语🌹
非常感谢您花时间阅读我的博客,希望我的分享能为您带来收获。如果您对本文有任何想法或疑问,欢迎在评论区留言交流。如果您喜欢我的博客,请继续关注,我会定期更新更多精彩内容。最后,别忘了行动起来的力量,让我们一起实践这些方法,见证自己的成长和进步!
再见,祝您生活愉快!