【C解析之五】函数:你不知道的事

C解析之五函数内幕


         前言:关于函数,你不知到的那些事。
          C语言程序 多个函数 组成 ,所有函数具有 平行性 ,这意味着函数内部不能再定义函数。 函数带来一大串问题,全局变量局部变量是什么?它们的作用域生存期有何不同?实际参数形式参数又有何不同?为什么形式参数只有在被调用时才分配内存?返回值如何传递......在很多书上都可以找到答案,但...问题是,很少有书给予了让人满意的解释。
          接下来尝试解开这些问题的原由,请看示例程序:

void Swap(int a,int b){  //形参a,b
	int temp;
	temp=a;
	a=b;
	b=temp;
}
int main(){
	int m=3;
	int n=4;
	Swap(m,n);           //实参n,m
	return 0;
}

下面是main()调用Swap()时栈示意图:
                                    
       1.main()调用前
                         1.1压栈保存现场:   main将寄存器数据与机器状态压栈保存,当调用结束后,把这些压入栈的数据弹出就可以恢复main的运行,如图main指示的区域。
                         1.2参数入栈:   参数列表(m,n)按从左到右的顺序压入栈。
                         1.3返回地址入栈: 这是main()函数的下一条指令的地址,保存这个地址返回main后才知道该执行main的那条指令。
        2.Swap()被调用
                         2.1建立自己的堆栈:Swap()在如图Swap指示的区域建立自己的堆栈,这是每个函数运行的基础,局部变量等空间开辟均基于堆栈。
                         2.2建立局部变量:  Swap()在自己的栈上建立局部变量(包括函数定义的形式参数),栈在Swap指示的区域。局部变量存储位置问题,可参考【C解析之三】C语言的内存分配
                         2.3 Swap开始执行指令:函数运行的条件-堆栈建立完成后,Swap开始执行代码,完成其任务。   
                          2.4参数的访问 : Swap通过基地址+偏移量访问参数,如基地址+8是第一个参数m,基地址+12是第二个参数n的地址,并将其值赋给建立的局部变量a,b。
       3.Swap()执行完后
                         3.1清理堆栈: Swap的任务已经完成,维持它运行的堆栈就没有存在的理由。
                         3.2返回值 : 如果有返回值,一般是将返回值放在寄存器中,main冲寄存器中获得返回值。
       4.main()恢复:
                        4.1返回地址 : 这条指令地址取出放入指令寄存器(处理器下一条处理的指令放在这个寄存器内)。
                         4.2弹栈恢复现场 :这个过程与1.1过程相反,恢复main调用前的环境。
                         4.3获取返回值 :如果有,一般到相应的寄存器内读取。
                至此,函数调用过程结束。现在分析这个过程,以期望可以找到问题的答案:
               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调用约定。

           
          
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值