// 1. 值傳遞
void Exchg1(int x, int y) {
int tmp = x; x = y; y = tmp;
printf("函數內 x=%d, y=%d\n", x, y);
}
// 2. 指針傳遞(地址傳遞)
void Exchg2(int *px, int *py) {
int tmp = *px; *px = *py; *py = tmp;
printf("函數內 *px=%d, *py=%d\n", *px, *py);
}
// 3. 引用傳遞
void Exchg3(int &x, int &y) {
int tmp = x; x = y; y = tmp;
printf("函數內 x=%d, y=%d\n", x, y);
}
int main() {
int a = 4, b = 6;
// Exchg1(a, b); // a=4, b=6 不變
// Exchg2(&a, &b); // a=6, b=4 交換成功
Exchg3(a, b); // a=6, b=4 交換成功
printf("main 內 a=%d, b=%d\n", a, b);
return 0;
}
| 模式 | 定義語法 | 調用語法 | 函數內操作對象 | 能否修改實參 |
|---|---|---|---|---|
| 值傳遞 | void f(int x) | f(a) | 副本 x | 否 |
| 指針傳遞 | void f(int *px) | f(&a) | 實參地址指向的內存 *px | 是 |
| 引用傳遞 | void f(int &x) | f(a) | 實參本身(別名) | 是 |
所有參數傳遞本質上都是「將實參的值複製給形參」。值傳遞複製變量值,指針傳遞複製地址值,引用傳遞在編譯器層面建立別名綁定。
| 場景 | 推薦 | 理由 |
|---|---|---|
| 輸入參數,不需修改,類型較小 | 值傳遞 | 簡單、安全、無副作用 |
| 輸入參數,不需修改,類型較大 | const 引用 | 避免拷貝開銷,語義清晰 |
| 輸出參數,需修改實參 | 引用 / 指針 | 引用語法更簡潔,指針可為 NULL 表可選 |
| C 語言環境 | 指針 | C 無引用機制 |
| 需表達「可選輸出」 | 指針 | 傳 NULL 表示不需要該輸出 |
& 或解引用 *理解三種模式的本質區別在於「函數內操作的是副本、地址指向的內存、還是別名綁定的原變量」。C++ 推薦優先使用引用(含 const 引用),C 僅能用指針,現代 C++ 更提倡值語義與移動語義減少顯式指針/引用使用。