C++ 參考是變數的**別名**,非獨立物件。本文詳細說明參考宣告/初始化規則、記憶體模型、與指標的本質差異、為何少用於區域變數別名、以及**函數參數傳遞**的最佳實踐 (含交換函數範例)。
int a = 5;
int& b = a; // 宣告參考,必須初始化
// int& c; // 錯誤:參考必須初始化
// int& d = 3; // 錯誤:需綁定左值
b = 3; // a 也變成 3
cout << a; // 輸出 3
&b == &a。int& b = a; int c = 3; b = c; 是**賦值操作**,非重新綁定;a, b 同變為 3。| 特性 | 參考 (int& r = a) | 指標 (int* p = &a) |
|---|---|---|
| 本質 | 別名,非物件 | 儲存位址的物件 |
| 佔用記憶體 | 通常不額外佔用 (編譯器內部用指標實作) | 需儲存位址 (32/64 位元) |
| 可否為空 | 不可 (必須綁定有效物件) | 可為 nullptr |
| 可否重新綁定 | 不可 (終身綁定初始化目標) | 可隨時 p = &other |
取位址 &r | 得到被參考者位址 (同 &a) | 得到指標變數本身位址 &p |
| 語法存取 | 透明 (如同原變數) | 需解參考 *p |
| 陣列/容器元素 | 不可建立參考陣列 | 可建立指標陣列 |
int a = 5;
int& b = a; // 同一記憶體有兩個名字
// 程式中後續操作 a 或 b,極易混淆「目前值到底是誰改的」
// 除錯時觀察變數表,看到 a, b 同步變化,增加認知負擔
**建議**:區域變數直接用原名;參考主要用於**函數參數**、**回傳值**、**範圍 for 迴圈變數**。
swap(x, y) vs swap(&x, &y),無需取址,閱讀者直接看出「會修改 x, y」。operator+, operator=, operator<< 皆以參考為標準。nullptr)。
// 參考版:呼叫 swap(x, y),閱讀性最佳
void swap(int& a, int& b) {
a = a + b;
b = a - b;
a = a - b;
}
// 指標版:呼叫 swap(&x, &y),需取址
void swapPtr(int* a, int* b) {
int tmp = *a; *a = *b; *b = tmp; // 較直觀的暫存變數法
}
參考版呼叫端 swap(x, y) 明確表達「x, y 將被修改」,指標版 swap(&x, &y) 需心理轉換。
int& getElement(vector& v, size_t i) { return v[i]; }
// 使用
getElement(vec, 0) = 42; // 直接修改容器元素
**注意**:不可回傳區域變數參考 (懸空參考,未定義行為)。
參考是「變數別名」,與被參考者共用記憶體、不可重新綁定、不可為空。函數參數傳遞**首選參考** (可讀性、安全性優於指標),除非需表達「可選」或「重新綁定」。理解參考與指標的記憶體模型差異,能寫出更符合 C++ 慣用語的程式碼。