值傳遞,即按值傳遞引數,按值傳遞引數時,是將實參變數的值複製乙個到臨時儲存單元中,如果在呼叫過程中改變了形參的值,不會影響實參變數本身,即實參變數保持呼叫前的值不變。
1、形參只能是變數,實參可以是常量、變數或表示式。在被定義的函式中,必須指定形參的型別。
2、實參與形參的個數應一樣,型別應一致。字元型和整型可以互相通用。
4、實參傳遞給形參是實參的值,形參變數在未出現函式呼叫時,並不占用記憶體,只在呼叫時才占用。呼叫結束後,將釋放記憶體。值傳遞過程中引數的資料傳遞是單向的,資料(實參的值)從實參傳遞形參,而不能由形參傳回實參。執行乙個被呼叫函式時,形參的值如果發生改變,並不會改變主調函式中的實參的值。
4、形參如同公式中的符號,實參就是符號具體的值,在呼叫過程前必須得到賦值;呼叫過程就是實現形參與實參的結合,把實參的值通過呼叫傳遞給形參,相當於把值代入公式進行計算。值傳遞的本質就是表示式。
位址傳遞,即按位址傳遞引數,按位址傳遞引數時,把實參變數的位址傳送給被呼叫過程,形參和實參共用記憶體的同一位址。在被呼叫過程中,形參的值一旦改變,相應實參的值也跟著改變。
1、實參必須是是變數,也就是保證可以重新被賦值或者初始化。在被定義的函式中,必須指定形參的型別。
2、實參與形參的個數應一樣,型別應一致。字元型和整型可以互相通用。
3、實參傳遞給形參的是實參變數的位址,函式呼叫過程中,並不為形參開闢儲存空間,也就是說位址傳遞過程中形參和實參共用實參的儲存空間,對形參的操作就是對實參本身的操作。
1、值傳遞實參向形參傳遞的是實參的值,而位址傳遞傳遞的卻是實參的位址。
2、值傳遞在函式呼叫過程中會為形參重新開闢空間,形參與實參分別占用不同的位址空間,而位址傳遞,形參和實參共用同一記憶體位址。
我們在引數傳遞過程中,只要抓住這兩點區別,就很好區別引數傳遞的具體方式。
下面我們將從形參和實參是普通型別變數、指標變數、陣列名時分別討論引數的傳遞方式。
簡單型別變數作實參,形參對應為型別一致的簡單型別變數,請看下面的程式
我們在主程式和函式中分別列印實參arg_value和形參par_value的位址和值,下面是程式在code::block12.11中的執行結果void fun_of_value(int par_value)
int main(void)
簡易的記憶體圖示如下:in main, the address of the value = 0028feec
in main, the value of the value = 10
in function, the address of the value = 0028fed0
in function, the value of the value = 10
很顯然在引數傳遞的過程中,實參arg_value和形參par_value具有相同的值,但是占用的儲存單元不相同,在函式中對形參的運算,對實參沒有影響,說明簡單型別變數在引數傳遞過程中是單向值傳遞的。
同樣我們在主程式和函式中分別列印實參arg_value和形參par_value的位址和值,下面是程式在code::block12.11中的執行結果void fun_of_point(int *par_point)
int main(void)
對結果分析後的圖示如下:the addreess og the value 0028feec
in main, the address of the point = 0028fee8
in main, the value of the point = 0028feec
in function, the address of the point = 0028fed0
in function, the value of the point = 0028feec
指標儲存的值其實是變數value的位址,我們發現,當引數是普通指標型別的時候,形參和實參都儲存著變數value的位址,也就是值相同,但是他們本身所占用的儲存單元卻不相同,即不共用儲存空間,我們不難得出當引數型別是普通指標變數時,引數傳遞也是值傳遞,只是傳遞的值是位址(實參的值),並不是「位址傳遞」。
執行結果如下:void function(void){}
void fun_of_fun_point(void(*par_pfun)(void))
int main(void)
對結果分析後的圖示如下:the address of the function = 004016c9
in main, the address of the function = 0028feec
in main, the value of the function = 004016c9
in function, the address of the function = 0028fed0
in function, the value of the function = 004016c9
與前面採取的方式類似,以函式指標作為引數與普通指著一樣,實參與形參都儲存了原函式的位址,但是他們本身的所占用的儲存單元並不相同,可見此時引數傳遞方式仍然是值傳遞,傳遞的值是函式function的位址。
程式的執行結果如下:void fun_of_array(int array)
void fun_of_array_point(int *array)
int main(void)
我們不難看出,陣列的位址和「陣列名的值」(我們暫且這樣稱呼)都儲存了陣列的首位址,其實大多數編譯器(如gcc)在處理的時候會在預處理階段把陣列名型別的引數轉換為指標型別的引數進行處理的,在編譯器看來,在以陣列名作為引數的時候陣列引數本質上為指標引數the addres of the first value 0028fec8
in main, the address of the array = 0028fec8
in main, the value of the array = 0028fec8
in function, the address of the array = 0028feb0
in function, the value of the array = 0028fec8
in function, the address of the arraypoint = 0028feb0
in function, the value of the arraypoint = 0028fec8
,即陣列引數和指標引數是完全等價的兩種形式,
因此以陣列名作為引數,本質上也是指標型別的引數傳遞,也採用單向值傳遞的方式。
由此我們不難得出結論,c
語言函式的所有引數傳遞均以「按值傳遞」
(單向值傳遞
)方式進行,在函式內部將獲得與形式引數值相同的乙份資料拷貝,函式的引數傳遞採用單向的值傳遞方式。當指標作為函式引數時,傳遞值是指標的值,即位址,依然是單向的值傳遞方式,並不是雙向的資料傳遞方式。
注意:引用傳遞是c99新引入的引數傳遞機制,但是目前為止,仍沒有一款編譯器完全支援c99標準,因此引用傳遞在此不進行討論,但是通過對資料的研究,其實引用傳遞本質也是採用指標傳遞的機制來實現的。
C 語言函式引數的傳遞
c 語言函式引數的傳遞 就像c語言眾多的後世子孫一樣,c 的函式引數是非常講究的。首先,引數必須寫在函式名後面的括號裡,這裡我們有必要稱其為形參。引數必須有乙個引數名稱和明確的型別宣告。該引數名稱只在函式體內部可見。因此在該函式體以外的任何地方使用同樣的變數名是不會引起衝突的。每當呼叫函式的時候,必...
c語言 函式引數的傳遞
程式一 值傳遞 include includeusing namespace std void exchg1 int x,int y int main 原因 函式在呼叫時是隱含地把實參a,b的值分別賦值給了x,y,之後在寫的函式體內再也沒有對a,b進行任何操作了。交換只是x,y變數。並不是a,b。當...
C語言函式引數的傳遞詳解
開講之前,我先請你做三道題目。嘿嘿,得先把你的頭腦搞昏才行 唉呀,誰扔我雞蛋?考題一,程式 如下 void exchg1 int x,int y main 輸出的結果為 x y a b 問下劃線的部分應是什麼,請完成。考題二,程式 如下 void exchg2 int px,int py main ...