C++引用傳遞:爲什麼函數參數要用&符號?

爲什麼函數參數要用&符號?——C++引用傳遞的祕密

你有沒有遇到過這樣的情況:寫一個函數想修改某個變量,結果發現修改後變量的值沒變化?或者處理一個很大的結構體,每次調用函數都要“複製”一份,既慢又佔內存?這時候,C++的引用傳遞就能派上用場了,而&符號就是它的“開關”。今天我們就來拆解一下,爲什麼函數參數需要用&,以及它到底是怎麼工作的。

先說說“值傳遞”的煩惱

在C++中,默認情況下函數參數是值傳遞的。什麼意思呢?就是函數接收的是實參的“副本”,而不是實參本身。比如下面這個交換兩個數的函數:

void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(x, y);
    cout << "交換後:x=" << x << ", y=" << y; // 這裏輸出的還是x=10, y=20
    return 0;
}

爲什麼沒交換成功?因爲swap函數里的abxy的“副本”。修改ab,只是修改了副本,原變量xy根本沒動。這就是值傳遞的侷限:如果要修改外部變量,值傳遞做不到。

什麼是“引用”?

“引用”(Reference)是C++的一個特性,它本質上是變量的別名。可以理解爲給原變量取了個“外號”,這個“外號”和原變量指向同一塊內存空間。比如:

int a = 10;
int &b = a; // b是a的引用,現在b和a指向同一塊內存
b = 20; // 修改b,實際上是修改了a
cout << a; // 輸出20(a也跟着變了)

這時候,如果把引用作爲函數參數,會發生什麼?

引用傳遞:用&讓函數“直接修改”外部變量

當函數參數用&聲明時,這個參數就是原變量的引用。這樣,函數里對參數的修改,就相當於直接修改了原變量。我們把剛纔的swap函數改成引用傳遞:

void swap(int &a, int &b) { // 參數前加&,表示引用傳遞
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(x, y); // 直接傳x和y,不用傳地址
    cout << "交換後:x=" << x << ", y=" << y; // 輸出x=20, y=10(成功修改!)
    return 0;
}

關鍵點&在這裏是“引用聲明符”,不是“取地址運算符”。當你寫int &a時,a就成了外部變量的引用,後續對a的操作都會影響原變量。

引用傳遞的“好處”

  1. 直接修改外部變量:不用像值傳遞那樣只能修改副本,能直接改實參。
  2. 避免大對象“拷貝浪費”:如果參數是一個很大的結構體或數組,值傳遞會複製整個對象(浪費時間和內存),而引用傳遞只傳遞一個“別名”,效率極高。比如處理一個10000個元素的數組,引用傳遞比值傳遞快得多。
  3. 代碼更簡潔:比用指針傳遞參數更直觀(後面會對比指針)。

別搞混!&的兩種身份

&在C++裏有兩個常見身份,別搞混了:
- 取地址運算符&var表示“取變量var的地址”,返回的是指針類型(比如int *)。
- 引用聲明符int &a表示“聲明a是int類型的引用”,必須在聲明時初始化(不能是nullptr)。

舉個對比:

// 引用參數(&是聲明符)
void func1(int &a) { a = 100; } 

// 指針參數(&是取地址運算符)
void func2(int *a) { *a = 100; } // 用指針要解引用*a

int main() {
    int x = 10;
    func1(x); // 直接傳x,引用參數修改x
    func2(&x); // 傳x的地址,指針參數修改x
    return 0;
}
  • 函數func1的參數是引用,調用時直接傳x
  • 函數func2的參數是指針,調用時需要傳&x(x的地址)。

引用的“注意事項”

  1. 必須初始化:引用聲明時必須綁定一個變量,不能寫成int &a;(這樣會報錯),必須像int &a = x;這樣。
  2. 不能“空引用”:引用不能指向nullptr,也不能被賦值爲0(指針可以)。
  3. 一旦綁定,不能改變指向:引用聲明後,永遠指向同一個變量,不像指針可以隨時換目標。

總結:什麼時候用引用傳遞?

  • 當需要修改外部變量時(值傳遞做不到);
  • 當處理大對象(結構體、數組等)時,避免拷貝浪費;
  • 當需要簡化代碼,用引用比用指針更直觀時。

記住,函數參數前加&就是“引用聲明符”,它讓函數能直接操作外部變量,而不用依賴複雜的指針解引用。下次寫函數時,如果發現值傳遞“改不動”變量,試試給參數加上&,讓函數成爲“變量的管家”吧!

小夜