栈的生长方向以及函数参数列表的压栈顺序

栈的生长方向以及函数参数列表的压栈顺序

标签(空格分隔): 栈的内存生长方向、函数参数压栈顺序、栈的特性


一、栈的特点

我们都知道栈的特性是先进后出,就好比一排汽车进入死胡同,只有最外面的汽车都倒车开走,最底部的汽车才能出来。就是说要访问栈底元素,必须先弹出栈顶元素,它区别于数组,不能通过下标访问元素。

二、栈的内存生长方向

从代码中看栈的内存生长方向:

#include <stdio.h>
#include <Windows.h>
using namespace std;

void test() {
	unsigned int a = 0;
	unsigned int b = 1;
	unsigned int c = 2;
	unsigned int d = 3;
	printf("a=%d,&a=%x\n", a, &a);
	printf("b=%d,&b=%x\n", b, &b);
	printf("c=%d,&c=%x\n", c, &c);
	printf("d=%d,&d=%x\n", d, &d);
}
int main() {
	test();
	system("pause");
	return 0;
}

输出结果:

从输出的结果可以看到:在函数内部定义的局部变量,先定义的变量在栈区占据高地址,后定义的变量占据低地址,可见栈的生长方向是向下的。需要注意的是,当函数调用结束之后,原先局部变量所分配的栈区都被回收,此时访问原先地址中的内容是不确定的。

三、函数参数的压栈顺序

让编译器说话:

#include <stdio.h>
#include <Windows.h>
using namespace std;

void test(int a,int b,int c) {
	printf("a=%d,&a=%x\n", a, &a);
	printf("b=%d,&b=%x\n", b, &b);
	printf("c=%d,&c=%x\n", c, &c);

}
int main() {
	test(100,200,300);
	system("pause");
	return 0;	
}

输出结果:

从输出结果可以看到变量c、b、a地址依次减小,我们又知道栈是向下生长的,所以函数参数列表的压栈顺序应当是从右往左的。请大家思考一下:为什么函数调用完之后会自动返回原先的调用处,继续执行剩下的代码呢?
其实,在调用test函数时,会把函数的返回地址优先压栈,这样等函数体执行完之后,会把返回地址弹出,程序依然能够正常往下执行。需要注意栈空间大小也是有限的,要避免栈溢出。

总结:
1、栈具有先进后出的特性。
2、栈是向下生长的,先定义的变量具有高地址,后定义的变量地址依次减小。
3、函数参数的压栈顺序是从右往左。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值