函式呼叫下形參和實參的記憶體分配
作為一個接觸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呼叫引數必須要壓棧,所以不佔記憶體是不現實的。