一、函式引數傳遞機制的基本理論:
函式引數傳遞機制問題在本質上是呼叫函式(過程)和被呼叫函式(過程)在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種:
值傳遞和
引用傳遞
。以下討論稱呼叫其他函式的函式為主調函式,被呼叫的函式為被調函式。
值傳遞(passl-by-value)過程中,被調函式的形式引數作為被調函式的
區域性變數處理
,即在堆疊中開闢了記憶體空間以存放由主調函式放進來的實 參的值,從而成為了實參的乙個
副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值(除非傳遞位址值)。
引 用傳遞(pass-by-reference)過程中,被調函式的形式引數雖然也作為
區域性變數
在堆疊中開闢了記憶體空間,但是這是存放的是由主調函式放進來的
實參變數的位址
。被調函式對形參的任何操作都被處理成
間接定址
,即通過堆疊中存放的位址訪問主調函式中的實參變數。正因為如此,被調函式對形參做的任何操作都影響了主調函式中的
實參變數。
二、c語言中函式引數傳遞機制
在c語言中,
值傳遞是唯一可用的引數傳遞機制
。但受指標變數作為函式引數的影響,容易誤認為這種情況是引用傳遞,這是
錯誤的。
使用「變數」作為函式引數進行傳遞,當呼叫函式時,其實本質是記憶體另外開闢乙個空間,將傳人的實參拷貝乙份給形參,即函式中處理的實際上是實參的乙個副本(形參),所以無論函式怎麼處理,實參的值是不會發生任何的改變的。
使用「指標」作為引數傳遞的情況,實際上和使用「變數」作為引數傳遞的情況是一樣的。只不過這裡的變數是乙個指標變數,傳的值是位址值。所以本質上還是傳值的方式。當我們將實參變數的位址,傳遞給函式的形參指標時,實際上是將實參的位址值賦給形參指標變數,然後後續的處理,
都是根據這個位址值進行索引找到實參的實際值進行處理
,所以函式處理的實際的實參的值,只不過是通過形參指標變數指向的。
int swap(int *x, int *y)
void main()
函式swap以兩個指標變數作為引數,當main()呼叫swap時,是以值傳遞的方式將指標變數p1、p2的值(也就是變數a、b的位址)放在了swap在堆疊中為形式引數x、y開闢的記憶體單元中。要點總結:
1)程序的堆疊儲存區是主調函式
和被調函式進行通訊的主要區域。
2)c語言中引數是從
右向左進棧
的。3)被調函式使用的堆疊區域結構為:
區域性變數(如temp),
返回位址,
函式引數,
低位址 ,
高位址4)由主調函式在呼叫後清理堆疊。
5)函式的返回值一般是放在暫存器中的。
三、c++語言中函式引數傳遞機制
c++既有c的值傳遞又有引用傳遞。在值傳遞上與c一致,這裡著重說明引用傳遞。如本文前面所述,
引用傳遞就是傳遞變數的位址到被調函式使用的堆疊中
。在c++中宣告引用傳遞要使用"&"符號,而呼叫時則不用
。下面的**是使用引用傳遞的swap2函式和main函式:
int& swap2(int& x, int& y)
void main()
此時函式swap2將接受兩個整型變數的位址,同時返回其中的乙個。而從main函式中對swap2的呼叫swap2(a, b)則看不出是否使用引用傳遞,是否使用引用傳遞,是由swap2函式的定義決定的。
這裡的swap2和前面的swap來講,堆疊中的函式引數存放的都是位址,在函式中操作的方式是一致的。但是,對swap2來說這個位址是主調函式通過將實參變數的偏移位址壓棧而傳遞進來的--這是引用傳遞;而對swap來說,這個位址是主調函式通過將實參變數的值壓棧而傳遞進來的--這是值傳遞,
只不過由於這個實參變數是指標變數所以其值是位址而已
。這裡的關鍵點在於,同樣是位址,乙個是引用傳遞中的變數位址,乙個是值傳遞中的指標變數的值。
雖然x是乙個區域性變數,但是由於其值是主調函式中的實參變數的位址,故在swap2中返回這個位址是合法的。
c++ 中經常使用的是
常量引用
,如將swap2改為:
swap2(const int& x; const int& y)
這時將不能在函式中修改引用位址所指向的內容,具體來說,x和y將不能出現在"="的左邊。
四、總結
1. 傳值和
傳常量引用
實參是不會被形參改變的。而如果函式體要改變實參的值,必須是傳指標或
非常量引用。2.
一般c++可以使用值傳遞和引用傳遞,後者更多。因為這樣不用另外在堆疊中開闢空間,而值傳遞就需要另外的開闢空間,對記憶體有一定的浪費。一般c中只使用值傳遞。
3.另外關於儲存資料方面,一般是將區域性變數,函式返回位址,函式引數放到堆疊中,而函式返回值一般放到暫存器中,為的是方便中斷,如果有臨時中斷就可以直接從暫存器中處理,不用再進行壓棧出棧操作。
函式的引數傳遞
def func a 1,b 2,c 3 形參有預設值 print a,b,c func func 4,5,6 func 5,6 func 7 func a 8 func a 9,b 10 func 11,c 12 func 11,a 12 和func a 12,13 是錯誤的 def calcsu...
函式引數的傳遞
先來幾道題壓壓驚先 第一題 void exchg1 int x,int y int main void 問題是x y a b 第二題 void exchg2 int px,int py int main void 問題是 px py a b 第三題 void exchg3 int x,int y i...
函式的引數傳遞
實參與形參 實參 全稱為 實際引數 是在呼叫時傳遞給函式的引數.實參可以是常量 變數 表示式 函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。形參 全稱為 形式引數 由於它不是實際存在變數,所以又稱虛擬變...