C解析之五函数内幕

[复制链接]
1744|17
 楼主| elecintop 发表于 2014-3-29 20:02 | 显示全部楼层 |阅读模式
前言:关于函数,你不知到的那些事。
         C语言程序由多个函数组成,所有函数具有平行性,这意味着函数内部不能再定义函数。函数带来一大串问题,全局变量与局部变量是什么?它们的作用域与生存期有何不同?实际参数与形式参数又有何不同?为什么形式参数只有在被调用时才分配内存?返回值如何传递......在很多书上都可以找到答案,但...问题是,很少有书给予了让人满意的解释。

 楼主| elecintop 发表于 2014-3-29 20:02 | 显示全部楼层
  1. void Swap(int a,int b){ //形参a,b
  2. int temp;
  3. temp=a;
  4. a=b;
  5. b=temp;
  6. }
  7. int main(){
  8. int m=3;
  9. int n=4;
  10. Swap(m,n); //实参n,m
  11. return 0;
  12. }
 楼主| elecintop 发表于 2014-3-29 20:02 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| elecintop 发表于 2014-3-29 20:03 | 显示全部楼层
      1.main()调用前:
                         1.1压栈保存现场:   main将寄存器数据与机器状态压栈保存,当调用结束后,把这些压入栈的数据弹出就可以恢复main的运行,如图main指示的区域。
                         1.2参数入栈:   参数列表(m,n)按从左到右的顺序压入栈。
                         1.3返回地址入栈: 这是main()函数的下一条指令的地址,保存这个地址返回main后才知道该执行main的那条指令。
 楼主| elecintop 发表于 2014-3-29 20:03 | 显示全部楼层
2.Swap()被调用后:
                         2.1建立自己的堆栈:Swap()在如图Swap指示的区域建立自己的堆栈,这是每个函数运行的基础,局部变量等空间开辟均基于堆栈。
                         2.2建立局部变量:  Swap()在自己的栈上建立局部变量(包括函数定义的形式参数),栈在Swap指示的区域。局部变量存储位置问题,可参考【C解析之三】C语言的内存分配。
 楼主| elecintop 发表于 2014-3-29 20:04 | 显示全部楼层
2.3 Swap开始执行指令:函数运行的条件-堆栈建立完成后,Swap开始执行代码,完成其任务。  
2.4参数的访问 : Swap通过基地址+偏移量访问参数,如基地址+8是第一个参数m,基地址+12是第二个参数n的地址,并将其值赋给建立的局部变量a,b。
 楼主| elecintop 发表于 2014-3-29 20:04 | 显示全部楼层
3.Swap()执行完后:
                         3.1清理堆栈: Swap的任务已经完成,维持它运行的堆栈就没有存在的理由。
                         3.2返回值 : 如果有返回值,一般是将返回值放在寄存器中,main冲寄存器中获得返回值
 楼主| elecintop 发表于 2014-3-29 20:04 | 显示全部楼层
  4.main()恢复:
                        4.1返回地址 : 这条指令地址取出放入指令寄存器(处理器下一条处理的指令放在这个寄存器内)。
                         4.2弹栈恢复现场 :这个过程与1.1过程相反,恢复main调用前的环境。
                         4.3获取返回值 :如果有,一般到相应的寄存器内读取。
                至此,函数调用过程结束。现在分析这个过程,以期望可以找到问题的答案:
 楼主| elecintop 发表于 2014-3-29 20:05 | 显示全部楼层
1.全局变量与局部变量:全局变量不依赖任何函数,至始至终都存在,存储于静态区。2.1-2.1到3.1可以发现,局部变量时在函数被调用后才开始分配空间,并最终随函数一起消亡。
               2.生存期: 全局变量显然在整个程序过程都一直存在,而局部变量生于函数调用时,死于函数调用结束。
               3.实际参数与形式参数:通过1.2与1.2-1.4清楚的表明,形式参数是函数的局部变量,创建于函数调用时,并被参数赋值。赋值则意味着在被调用函数内的操作,将不会影响到实参m,n的值,Swap并不具有m,n互换的功能。(读者可以试试,实际上Swap(int &a,int &b)这样定义才具有交换的功能)。
               4.参数的传递 :参数的传递是通过地址偏移量完成,其中更多的细节参考C调用约定。
               5.返回值: 一般情况下,返回值通过寄存器传递,更多细节参考C调用约定。
yanyanyan168 发表于 2014-3-29 21:05 | 显示全部楼层
学习了!!
sgj245609615 发表于 2014-3-29 22:39 | 显示全部楼层
学习下
smilingangel 发表于 2014-4-20 21:55 | 显示全部楼层
elecintop 发表于 2014-3-29 20:03
1.main()调用前:
                         1.1压栈保存现场:   main将寄存器数据与机器状态压栈保 ...

这个过程讲解还是蛮好的,,我参考了,谢谢
monkeypony 发表于 2014-4-21 16:44 | 显示全部楼层
谢谢楼主分享!
angerbird 发表于 2014-4-21 22:22 | 显示全部楼层
全局变量与局部变量:全局变量不依赖任何函数,至始至终都存在,存储于静态区
angerbird 发表于 2014-4-21 22:22 | 显示全部楼层
局部变量时在函数被调用后才开始分配空间,并最终随函数一起消亡。
angerbird 发表于 2014-4-21 22:23 | 显示全部楼层
全局变量显然在整个程序过程都一直存在,而局部变量生于函数调用时,死于函数调用结束。
angerbird 发表于 2014-4-21 22:23 | 显示全部楼层
形式参数是函数的局部变量,创建于函数调用时,并被参数赋值。赋值则意味着在被调用函数内的操作,将不会影响到实参的值
firstblood 发表于 2014-4-22 19:33 | 显示全部楼层
学习下的啊,局部变量跟全局变量的用法是有很大区别的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

176

主题

1329

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部