-
1 # 三袋大菠蘿
-
2 # C語言答疑課堂
C語言中自定義函式一個最常見的注意點就是區分“值傳遞”和“址傳遞”了。“值傳遞”和“址傳遞”就一個字不一樣,而且發音還非常的接近,但就是天壤之別。許多初學C語言的小夥伴經常搞不清透過函式傳遞一個數據值和傳遞一個地址,以至於C程式的執行結果大相徑庭。本回答就來詳細講解下C語言中“址傳遞”和“值傳遞”的區別。
一、值傳遞和址傳遞的C程式程式碼為了說清“值傳遞”和“址傳遞”之間的區別,我們先看一段C程式程式碼,如下:
上述C程式程式碼非常簡單:在C程式的main函式中定義了兩個整型變數para1與para2,初始值分別是1和2;還有一個指標變數pInt,初始值是變數para2的地址。
在C程式的main函式中,先呼叫了自定義函式ValueTrans,並且把變數para1作為引數。在自定義函式ValueTrans中,將變數para1重新賦值為11。在呼叫完函式ValueTrans後輸出變數para1的值,看看是多少;
在C程式的main函式中,再次呼叫了自定義函式AddrTrans,並且把指標pInt作為引數。在自定義函式AddrTrans中,將指標pInt指向的值重新賦值為22。在呼叫完函式AddrTrans後輸出變數para2的值,看看是多少;
現在我們看看這段C程式的執行結果:
驚不驚喜?意不意外?
二、值傳遞和址傳遞的解釋現在我們來解釋下上述C程式程式碼為何是這麼個執行結果。
1、值傳遞
上述C程式程式碼呼叫函式ValueTrans,把變數para1作為引數,注意就是把變數para1的值1作為引數。
在具體執行函式ValueTrans時,系統自己默默地、悄悄地在某一個地方新建了一個也叫作para1的整型變數。這個整型變數para1可不是C程式程式碼main函式中的那個para1.我們可以把main函式中的para1變數看做是main_para1,把函式ValueTrans中的para1看做是ValueTrans_para1.那麼在函式ValueTrans中其實是把11賦值給了變數ValueTrans_para1,至於變數main_para1嘛,紋絲不動!
所以在C程式main函式中,最後變數para1的值還是1.
2、址傳遞
上述C程式程式碼呼叫函式AddrTrans,把指標pInt作為引數,注意此時就是把變數para2的地址作為引數,這就有意思啦!
在具體執行函式AddrTrans時,系統自己同樣地、悄悄地在某一個地方新建了一個也叫作pInt的指標變數。但是這個指標變數pInt的值就是main函式中的那個pInt的值.換句話說,兩個指標變數pInt同時指向了C程式中main函式的變數para2。那麼在函式AddrTrans中把22賦值給了指標pInt指向的值,其實也就改變了main函式中的變數para2的值,太神奇了!這就是C語言指標的魅力所在!
所以在C程式main函式中,最後變數para2的值就變成了22.
上述是C語言程式設計中自定義函式時要注意的一個地方。你明白了嗎?
回覆列表
函式在彙編這一層可以看做機器程式碼和編譯器之間的約定。拿32位arm的CPU為例,前4個引數用CPU暫存器傳遞。呼叫函式之前,會把引數從記憶體中讀取到這4個暫存器中。第5個引數開始,壓入堆疊。堆疊是用DDR記憶體實現的。在函式退出時,又要出棧。引數資料準備好之後,就是一個跳轉指令。因此,C語言中,函式傳遞引數最好不要超過4個。而函式返回引數一般用暫存器r0.