函数调用下形参和实参的内存分配

来源:互联网 发布:淘宝上的epiphone 编辑:程序博客网 时间:2024/05/21 17:11

   作为一个接触C/C++不久的小菜鸟,常常对函数形参和实参的内存分配和调用很费解,现就最近心得总结如下;

函数形参和 实参具有以下特点

#include<iostream.h>

int Max(int x,int y)

{

   return x>y? x:y;

}

void main()

{

   cout<<"Max is..."<<Max(4,8)<<endl;  //函数调用

}

1,形参变量只有在被调用时才分配内存单元,在调用结束后,即可释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参那变量。

2、实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须具有确定的值,以便吧这些值传送给形参。因此,预先用赋值、输入等方法是实参获得确定值。

3、实参和形参在数量上、类型上、顺序上应严格一致,否则会发生类型不匹配的错误;

4、函数调用中发生的数据传送是单向的。即只能把实参传送给形参,而不能把形参的值传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会发生改变。

 形参只在这个函数执行的时候才会被分配内存,当函数执行完毕后分配的内存会被释放。至于理由……函数的参数属于局部变量,如果一开始就分配的话,别的地方也能访问修改,数据就不确定了。
另外,函数的形参实际是:调用此函数前,将实参压入堆栈,然后跳转到函数的地址执行。函数执行完跳回去时,堆栈弹出,内存释放。

当一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:

   1、将所有的实参、返回地址等信息传递给被调函数保存。

   2、为被调函数的局部变量(包括形参)分配内存空间;

   3、将控制转移到被调函数的入口;



从被调函数返回主调函数之前,系统也要完成三件事

    1、保存被调函数的返回结果;

     2、释放被调函数所占的存储空间;

     3、依照被调函数返回的地址将控制转移到调用函数;

当有多个函数调用时,按照“后调用先返回”的原则,上述函数之间的信息传递和控制转移必须借助“栈”来实现,机系统整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储区,执行出栈操作,当前运行的函数永远就在栈顶位置。


具体内存分配细解可参看<<C深度剖析>>


那么在什么情况下不给形参和实参分配内存大小呢?????

Windows中以__fastcall调用的时候是可以的,因为前两个参数不被放到堆栈中传入,而是传到寄存器中,这样可以不占用内存。


c方式的_cdecl调用参数必须要压栈,所以不占内存是不现实的。