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. 一旦绑定,不能改变指向:引用声明后,永远指向同一个变量,不像指针可以随时换目标。

总结:什么时候用引用传递?

  • 当需要修改外部变量时(值传递做不到);
  • 当处理大对象(结构体、数组等)时,避免拷贝浪费;
  • 当需要简化代码,用引用比用指针更直观时。

记住,函数参数前加&就是“引用声明符”,它让函数能直接操作外部变量,而不用依赖复杂的指针解引用。下次写函数时,如果发现值传递“改不动”变量,试试给参数加上&,让函数成为“变量的管家”吧!

Xiaoye