1. 程式人生 > >函式呼叫下形參和實參的記憶體分配

函式呼叫下形參和實參的記憶體分配

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