写 C++ 时你一定见过 & 这个符号:它有时出现在变量前面表示"取地址",有时又出现在类型后面,比如 int& x。后者就是本篇的主角——引用(reference)。理解了引用,你就能看懂很多函数签名,也能写出更高效的代码。
什么是引用:变量的别名
引用就是给已经存在的变量起一个"别名",对别名的任何操作,都等价于对原变量本身的操作。
#include <iostream>
using namespace std;
int main() {
int score = 90;
int& alias = score; // alias 是 score 的引用(别名)
alias = 95; // 修改 alias 就是修改 score
cout << score << endl; // 输出:95
cout << &score << endl; // 输出:0x7ffc2a8(示意)
cout << &alias << endl; // 与上一行地址完全相同
return 0;
}
注意最后一组输出:score 和 alias 的地址一模一样,因为它们本来就是同一块内存的两个名字。
引用必须在定义时绑定,且终身不改
引用和普通变量最大的区别有两点:一是定义时必须初始化,二是绑定之后不能再"改嫁"。
int a = 10;
int b = 20;
int& r = a; // r 从此只代表 a
r = b; // 注意:这不是让 r 改绑 b,而是把 b 的值赋给 a!
cout << a << endl; // 输出:20
cout << &r << " " << &a << endl; // 地址仍然相同
很多初学者以为 r = b 是让引用改指 b,实际上引用一旦绑定就永远不会改变指向,这句代码的效果就是普通的赋值。另外,也不存在"空引用",引用必须一开始就绑定到一个真实存在的变量。
引用作为函数参数:最实用的场景
引用最常见的用途是函数传参。C++ 的函数参数默认是"值传递",函数收到的是一份拷贝,改它不影响外面;换成引用传递,函数里拿到的就是原变量本身。
#include <iostream>
using namespace std;
// 值传递:交换的是拷贝,无效
void swap_bad(int x, int y) {
int tmp = x; x = y; y = tmp;
}
// 引用传递:交换的是原变量,有效
void swap(int& x, int& y) {
int tmp = x; x = y; y = tmp;
}
int main() {
int a = 1, b = 2;
swap_bad(a, b);
cout << a << " " << b << endl; // 输出:1 2(没换过来)
swap(a, b);
cout << a << " " << b << endl; // 输出:2 1(成功交换)
return 0;
}
除了能修改原变量,引用传参还有一个好处:避免大对象拷贝。比如函数参数是 string 或自定义类时,用 const string& s 既不拷贝又不允许修改,是标准写法。
引用作为函数返回值
函数也可以返回引用,典型用法是"链式访问"某个需要被修改的元素:
#include <iostream>
using namespace std;
int& bigger(int& a, int& b) {
return (a > b) ? a : b; // 返回较大者的引用
}
int main() {
int x = 3, y = 8;
bigger(x, y) = 100; // 给返回的引用赋值,等价于 y = 100
cout << y << endl; // 输出:100
return 0;
}
有一条红线必须记住:永远不要返回局部变量的引用。局部变量在函数结束时就被销毁了,返回它的引用等于返回一块已经失效的内存,程序行为不可预测。
引用与指针的区别
引用和指针都能"间接操作变量",但它们是两种东西:
- 引用定义时必须初始化;指针可以先声明后赋值,甚至暂时指向空。
- 引用绑定后不能更改;指针随时可以改指别的地址。
- 不存在空引用;存在空指针。
- 引用用起来就像原变量本身,不需要
*解引用;指针必须通过*访问目标。
一个简单的选择原则:能在"引用一个确定存在的对象"的场景下用引用,就用引用;需要"可能什么都不指"或"中途改变指向"时,才用指针。
小结
- 引用是变量的别名,
int& r = a;之后操作r就是操作a,二者地址相同。 - 引用必须初始化,且绑定后不能改指向,也不存在空引用。
- 引用传参让函数直接修改原变量,还能避免大对象拷贝,常量引用
const T&是只读大参数的标准写法。 - 函数可以返回引用,但严禁返回局部变量的引用。
- 与指针相比,引用更安全、更直观;需要"可空"或"可改指"时再选指针。
评论 0
还没有评论,来抢沙发吧~ 🛋