Q4 傳遞參數方式主要包含:傳值呼叫 (call-by-value)、傳址呼叫 (call-by-address)、傳參照呼叫 (call-by-reference)、傳名呼叫 (call-by-name)。請解釋這些方式在被呼叫副程式(callee subroutine)與呼叫者(caller)之間的資料傳遞差異,以及副程式結束後實際參數是否會受到影響。
🔹 參數傳遞方式比較
當呼叫者 (caller) 將參數傳入被呼叫副程式 (callee subroutine) 時,不同的傳遞方式會影響 副程式內部對參數的操作方式,以及 呼叫結束後實際參數是否會改變。以下逐一說明:
1️⃣ 傳值呼叫 (Call by Value)
-
機制:呼叫時,會將 實際參數的值複製一份 傳給副程式。
-
影響:副程式僅能操作這份「複本」,不會影響原始的實際參數。
-
結果:副程式結束後,實際參數不變。
-
範例:C 語言傳遞基本型別。
2️⃣ 傳址呼叫 (Call by Address)
-
機制:呼叫時,會將 實際參數的記憶體位址 (指標) 傳入副程式。
-
影響:副程式若透過該位址修改內容,會直接作用於呼叫者的實際參數。
-
結果:副程式結束後,實際參數可能改變。
-
範例:C 語言以指標 (
int *p
) 參數傳遞。
3️⃣ 傳參照呼叫 (Call by Reference)
-
機制:呼叫時,傳入的是 實際參數的參照 (reference),就像是替呼叫者的變數取了一個「別名」。
-
影響:副程式內對參數的修改,會直接反映在呼叫者的實際參數上。
-
結果:副程式結束後,實際參數可能改變。
-
範例:C++ 的參照 (
int &x
),或 Java 的物件傳遞(嚴格來說是「值傳遞參照」)。
4️⃣ 傳名呼叫 (Call by Name)
-
機制:呼叫時,傳入的不是值或位址,而是 一段可以重新計算的表達式。副程式每次使用該參數時,會「回頭」以文字替換或延遲計算的方式來求值。
-
影響:效果類似巨集展開,每次取用都會重新計算,可能導致副作用。
-
結果:實際參數是否改變,取決於該表達式的內容與副程式操作方式。
-
範例:ALGOL 語言、Scala(透過
=>
call-by-name 參數)。
沒有留言:
張貼留言