值傳遞和位址傳遞,C語言函式傳參方式詳解

2021-09-27 09:14:19 字數 2121 閱讀 9860

在 c 語言中,函式的引數傳遞方式有兩種:值傳遞與位址傳遞。下面分別介紹這兩種傳遞形式。

這種方式使用變數、常量、陣列元素作為函式引數,實際是將實參的值複製到形參相應的儲存單元中,即形參和實參分別占用不同的儲存單元,這種傳遞方式稱為「引數的值傳遞」或者「函式的傳值呼叫」。

值傳遞的特點是單向傳遞,即主調函式呼叫時給形參分配儲存單元,把實參的值傳遞給形參,在呼叫結束後,形參的儲存單元被釋放,而形參值的任何變化都不會影響到實參的值,實參的儲存單元仍保留並維持數值不變。

來看下面乙個呼叫示例:

#include /* 變數x、y為swap函式的形式引數 */

void swap(int x, int y)

int main(void)

在上面這個示例**中,實參將值傳遞給形參,形參值發生互換後的值不能回傳給主調函式。因此,主調函式中的數值不變,**的執行結果為:

x = 20, y = 10

a = 10, b = 20

對於上面這個示例,或許有人會有如下疑問:上面的示例中明確地把 a、b 分別代入了 x、y 中,並在函式 swap() 裡完成了兩個變數值的交換,為什麼 a、b 變數值還是沒有交換。其結果仍然是「a=10,b=20」,而不是「a=20,b=10」呢?

其實,原因很簡單。函式在呼叫時,隱含地把實參 a 的值賦值給了引數 x,而將實參 b 的值賦值給了引數 y,如下面的**所示:

/*將a的值賦值給x(隱含動作)*/

int x = a;

/*將a的值賦值給y(隱含動作)*/

int y = b;

因此,之後在 swap() 函式體內再也沒有對 a、b 進行任何操作。而在 swap() 函式體內交換的只是 x、y,並不是 a、b,當然,a、b 的值沒有改變。整個 swap() 函式呼叫是按照如下順序執行的:

/*將a的值賦值給x(隱含動作)*/

int x = a;

/*將a的值賦值給y(隱含動作)*/

int y = b;

int tmp;

tmp = x;

x = y;

y = tmp;

printf("x = %d, y = %d\n", x, y);

由此可見,函式只是把 a、b 的值通過賦值傳遞給 x、y,在函式 swap() 中操作的只是 x、y 的值,並不是 a、b 的值,這也就是所謂的引數的值傳遞。

這種方式使用陣列名或者指標作為函式引數,傳遞的是該陣列的首位址或指標的值,而形參接收到的是位址,即指向實參的儲存單元,形參和實參占用相同的儲存單元,這種傳遞方式稱為「引數的位址傳遞」。

位址傳遞的特點是形參並不存在儲存空間,編譯系統不為形引數組分配記憶體。陣列名或指標就是一組連續空間的首位址。因此在陣列名或指標作函式引數時所進行的傳送只是位址傳送,形參在取得該首位址之後,與實參共同擁有一段記憶體空間,形參的變化也就是實參的變化。

來看下面乙個呼叫示例:

void swap(int *px, int *py)

int main(void)

px = &a;

py = &b;

注意,這裡與值傳遞方式存在著很大的區別。在值傳遞方式中,傳遞的是變數 a、b 的內容(即在上面的值傳遞示例**中,將 a、b 的內容傳遞給引數 x、y);而這裡的位址傳遞方式則是將變數 a、b 的位址值(&a、&b)傳遞給引數 px、py。因此,整個 swap() 函式呼叫是按照如下順序執行的:

/*將&a的值賦值給px(隱含動作)*/

px = &a; /* ← */

/*將&b的值賦值給py(隱含動作)*/

py = &b;

int tmp;

tmp = *px;

*px = *py;

*py = tmp;

printf("*px = %d, *py = %d\n", *px, *py);

這樣,有了前兩行的隱含賦值操作,指標變數 px、py 的值已經分別是變數 a、b 的位址值(&a、&b)。接下來,對「*px」「*py」的操作當然也就是對 a、b 變數本身的操作了。所以 swap() 函式中的交換操作就是對 a、b 值進行交換,這就是所謂的位址傳遞,執行結果為:

*px = 20, *py = 10

a = 20, b = 10

c 函式傳參 值傳遞 指標傳遞 引用傳遞

1 將變數名作為實參和形參 這時傳給形參的是變數的值,傳遞是單向的。如果在執行函式期間形參的值發生變化,並不傳回實參。應為在呼叫函式時,形參和實參不是同乙個儲存單元。2 傳遞變數的指標 形參是指標變數,實參是乙個變數的位址,呼叫函式時,形參指向實參變數單元。可以通過形參指標修改實參的值。3 c 提供...

C語言 值傳遞 位址傳遞

1.值傳遞 void exchg1 int x,int y main 呼叫exchg1 a,b 有乙個隱含的操作就是int x a int y b 然後函式內部把形參x和y的值對換。所以a和b的值各自不變。2.位址傳遞 void exchg2 int px,int py main 同樣的,呼叫exc...

C語言 關於值傳遞和位址傳遞

初學者在學習c語言時候乙個極容易迷惑的地方就在函式的 值傳遞 和 位址傳遞 了,出現這個迷惑的原因有些教材沒有把記憶體圖畫出來,只是簡單的舉了幾個例子,結果初學者按照例子寫寫 倒是能執行出來,但始終沒明白到底是怎麼回事,下面我通過例子和畫圖來相信說明裡面的細節問題。在開始之前有乙個前提,你一定要粗略...