从系统堆栈角度理解实参与形参

从系统堆栈角度理解实参与形参

 

 

        实参与形参,相信是很多朋友学习C语言的一大难点。晦涩难懂难以理解。

百度上搜到的只是说形参和实参的功能是作数据传送。那么到底是如何进行数据传递的呢?下面我就从系统堆栈角度讲解一下:

先举一个小栗子:

#include<stdio.h>
void exchange(int,int);

void exchange(int one, int another){
    int tmp;
    tmp = one;
    one = another;
    another = tmp;

}
int main(){
    int num1 = 14;
    int num2 = 7;
    exchange(num1,num2);
    printf("交换后的数值:%d  %d", num1, num2);


     return 0;
}

        这是一个交换两个数值的一个小程序,看起来是没有什么问题的,但是编译运行,

立马发现问题所在了,没错,其值并没有被交换。

      因为在一般传值调用的机制中只能把实参传送给形参,而不能把形参的值反向地传送给实参。

在上述程序中,exchange()函数交换的只是函数中的形参的值,而主函数中的实参的值根本

没有被交换。下面从对堆栈角度说一下(不理解堆栈的请自行百度)

 

        如图所示:当主函数定义实参num1,num2时,其值会自动入栈,然后调用exchange()函数,

在此之前,操作系统会将主函数main()的现场信息(目前只有eip)指针入栈保存,然后开始调用

exchange()子函数,将子函数的首地址常量赋值给栈底指针ebp,然后使栈顶指针esp和栈底指针ebp

指向同一空间,形成空栈,然后此空栈由子函数exchange()调用。调用过程中会将其定义的形参

从右向左入栈,即形参another先入栈,按照从右向左的顺序,实参num2将其值7传递给another,

形参one后入栈,num1将其值14传递给one,最后子函数定义的变量tmp入栈。然后开始执行

exchange()子函数:

 

    tmp = one;
    one = another;
    another = tmp;

经过赋值,one和another的值发生交换。

然后子函数exchange()调用完毕,栈顶指针回到栈底指针位置,恢复子函数调用之前的状态,

然后输出实参num1和num2,可以很清楚的发现,num1和num2的值并没有发生改变,

只是将其值传递给子函数内的形参one和another,exchange()子函数调换了形参one和another的值,

因此上述代码不能完成值的交换。真正需要交换的不是实参的值,而是实参的地址,代码如下:
 

#include<stdio.h>

void realexchange(int *, int *);

void realexchange(int *one ,int *another){
    int tmp;
    tmp = *one;
    *one = *another;
    *another = tmp;
}
int main(){                                                             
    int num1 = 14;
    int num2 = 7;
    realexchange(&num1,&num2);
    printf("交换后的两个值:%d %d",num1,num2);

    return 0;
}

 

这段修改后的代码表达意思如图所示:

 

 

 

 

 

    子函数中形参得到的传递的值是实参num1和num2的地址,经过exchange()子函数交换之后,

num1和num2的地址被交换, 所以最后输出的值就是经过交换的!

    也就是说,实参表达式的值入栈所占用的空间,就是对应的形参的空间。而实参表达式的值入栈,

是将其值复制一份去入栈,因此exchange()函数第一次失败了。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值