注意 : 以下是在常见开发工具 keil 中运行的结果.
1.下面的代码输出的a是多少 ?
void test0(void)
{
int a = 5;
int arr[4] = { 0 };
a++;
arr[5] = 10;
printf("a = %d\r\n", a);
}
int main()
{
test0();
while(1) { }
return 0;
}
答案:10.
2.如果运行这段代码会发生什么 ?
void test0(void)
{
int index = 7;
int arr[5] = { 0 };
printf("test1\r\n");
*((short*)&arr[index])= 0x101;
}
int main()
{
test0();
while(1) { }
return 0;
}
答案:会一直输出test1.
3.如果运行这段代码会发生什么 ?
void test1(void)
{
int index = 7;
int arr[5] = { 0 };
printf("test1\r\n");
arr[index] = (int)test2;
}
void test2(void)
{
int index = 7;
int arr[5] = { 0 };
printf("test2\r\n");
arr[index] = (int)test1;
}
int main()
{
test1();
while(1) { }
return 0;
}
答案:会一直交替输出test1 test2.
如果你知道为什么? 那么恭喜你对栈的理解很达标, 如果不理解没关系, 我们接下来就来分析一下为什么.
我们知道当C语言调用一个函数时候会进行会将lr寄存器压入栈, 而lr储存的是该函数下一行的地址,也就是函数的返回地址,对于第一题我们可以观察出函数栈:
也就是说arr[5]对应地址其实是a的地址,将arr[5]赋值为10, 自然a之前的值也被覆盖看了.
对于后面两题也就显而易见, 将lr改了,自然函数的返回地址也就改了.