作为一个接触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调用参数必须要压栈,所以不占内存是不现实的。