C 語言

傳值呼叫

想像你影印一份文件,把影本交給某人。他們可以在自己的影本上盡情塗寫,但你的正本毫髮無傷。C 把引數傳給函式正是這樣:它複製你給的值,把那份副本交給函式。函式對它的參數做什麼,呼叫端那邊你的正本變數都不受影響。

當你呼叫 f(x),C 求值 x、製作那個值的一份全新副本,並把它綁到 f 的參數。那個參數是一個獨立的區域變數,只是剛好以同樣的值開始。所以若 f 把一個新值指派給它的參數,只有副本改變;呼叫端的 x 保留它的原值。這是 C 唯一的引數傳遞規則——C 沒有內建的傳參考呼叫。要讓函式能改動呼叫端的變數,你傳那個變數的位址(一個指標):指標值仍是以值複製的,但它指回正本,所以解參考它就能觸及真正的物件。

為什麼重要:傳值呼叫正是為什麼一個天真的、只重新指派兩個 int 參數的交換函式,對呼叫端的變數毫無作用——一個經典的初學者驚訝。懂這個規則就確切知道你何時需要一個指標參數(為了修改正本,或為了避免複製一個大型結構)。還有一個微妙但重要的點:傳一個指標仍是以值傳遞那個指標;你複製的是位址,不是被指物。

void try_change(int n) { n = 99; } /* 只改動副本 */ int x = 5; try_change(x); /* 之後 x 仍是 5 */ /* 要真正改動 x,傳它的位址: */ void set(int *p) { *p = 99; } set(&x); /* 現在 x 是 99 */

try_change 編輯一份副本,所以 x 不變;set 接收 x 的位址並透過它寫入,所以 x 真的改變。

C 一律是傳值呼叫——沒有傳參考呼叫。傳一個指標仍是以值複製那個指標(位址);函式能觸及正本,只是因為那份被複製的位址仍指向它。

又稱
call by value傳值值傳遞