Chinaunix首页 | 论坛 | 博客
  • 博客访问: 97699
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-11 22:44
个人简介

HUST16届准毕业生,发奋求职中...

文章分类

全部博文(21)

文章存档

2015年(17)

2014年(4)

我的朋友

分类: C/C++

2015-04-09 14:07:11

     调用函数的传参顺序是从右向左,c语言之所以将传参顺序设为从右向左,是为了支持可变参数函数。

    可变参数函数,我们接触最多的应该是printf,一般printf("%d\n,%d\n,....", a,b,...)这样使用的时候,传递给printf的参数的个数是不确定的。如果想要使用自定义的可变参数函数的话,需要包含stdarg.h这个头文件。
 

那为什么从右向左传递参数就能支持可变参数函数的实现呢?


我在网上查找了好多资料,也恶补了下c语言函数调用过程中栈的变化。

   首先,必须理解最基本的知识,栈是向下生长的,即栈顶的地址要比栈底的地址低。可以利用这个结论,查看调用函数参数的地址,验证参数入栈的顺序。

   其次,理解两个指针,ebp和esp,ebp中b代表base,ebp代表栈底指针,esp中s代表stack,esp代表栈顶指针。、

   然后,就要分析函数调用的过程了,假设函数A调用函数B,A是调用者,B是调用者。调用过程如下:

          (1)、现将函数A的堆栈的ebp入栈,以保存之前任务的信息。

          (2)、然后将A的栈顶指针esp赋值给ebp,作为新的基址,即被调用函数B的栈底是调用函数A的栈顶。

          (3)、然后在这个基址上,开辟相应的空间,用来存放B函数中的局部变量

          (4)、当函数B返回时,从当前栈帧的ebp即可恢复调用者A的栈顶esp,使栈顶恢复到调用B之前的位置,然后A在从恢复后的栈顶可弹出之前的ebp,ebp和esp都恢复到调用B之前的位置。


 从这个图形可以看出,只有从右往左入栈,才能够实现可变参数,因为从右向左入栈,所以第一个参数可以通过被调函数的ebp的一个偏移量直接获得。而如果是从左向右偏移的话,与ebp相邻的则是最后一个参数,而获得第一个参数的偏移量是和参数的个数相关的。

阅读(3571) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~