函数调用机制

Posted 菜鸟开车

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数调用机制相关的知识,希望对你有一定的参考价值。

  函数也是一段代码,在内存里会有一段空间来存储这个函数的操作指令和操作数据,所以函数在程序里也可以看作相对一个独立的部门,这个部门属于引用的程序,调用的时候找到这个函数的内存的地址,并且传递相应的参数给这个部门(函数)就行,所以关键问题就是怎么调用函数以及怎么给这个函数传递参数。

  

  假如要调用函数Addnum(num_a,num_b)实现两个数相加,现在已经通过函数地址找到了这个函数,怎么把num_a,num_b给这个函数呢?这里可以用这样个比喻,假如一个快递员,要给一个部门送两个包裹,快递员通过这个部门的地址找到这个部门,然后敲门,但是这个部门的人不方便直接来取包裹,他们在门口贴了张纸,上面写着:门右边有个桶,你把包裹放在那个桶里吧,记得把先给我的包放最上面,然后快递员按要求把num_b先放进去,然后是num_a,这样这个部门取包裹的时候就先取出了num_a,然后再取出num_b, 部门的工作人员从桶里拿出这两个包裹的然后就可以开始运作了。

  

  上面的部门就是函数,通过地址找到这个部门就是汇编的call指令,门口那个桶就是程序运行时申请分配的内存空间,也就是栈,往栈里放东西用push,取东西用pop,由于取的时候先取上面的,所以放的时候顺序要反过来放。

  

  现在继续拓展前面的比喻,这个快递员不仅要送包裹到指定部门,到了目的地后,还要等待这个部门把事情处理完,然后把处理完的反馈包裹送回到原来的地方,这样原来的客户拿到包裹就可以继续干活了,但是这个快递员有个缺点,就是记性不好,所以他干脆得把回去的地址也放到桶里,这样等下回去的时候,从桶里拿出回去的地址就可以了。

  

  这个比喻可能不是很恰当,主要是说程序处理完还要返回到原来的程序执行流程节点上,在汇编里就是用return指令。  

 

  前面学习了下函数式宏,函数式宏并不是函数,在编译的时候函数式宏会进行替换展开,如果有很多地方引用了函数式宏,每一个地方都会进行替换展开,所以程序也会变大,这就是为什么简短且调用频率高的时候可以考虑用函数式宏,如果是普通函数调用则不会出现因为调用次数越多,代码越多的情况。

以上是关于函数调用机制的主要内容,如果未能解决你的问题,请参考以下文章

函数调用机制

函数调用机制2

gdb 使用啥机制来知道在哪里“完成”函数调用?

Swift中的函数调用

Mono生命周期函数调用机制分析

runtime