原来这么简单:C++引用(&)的基础用法

在C++中,引用(&)是一个非常重要的概念,它能让我们更高效地操作变量,避免不必要的数据拷贝。但对于初学者来说,引用的语法和使用场景可能有点抽象。别担心,今天我们就用最简单的方式,从“是什么”“怎么用”“注意啥”三个方面,把引用的基础用法讲清楚。

一、引用到底是什么?

想象一下,你有一个好朋友叫“小明”,但他有个外号叫“明哥”。你用“小明”或“明哥”叫他,指的都是同一个人。C++的引用就像这个“外号”——引用是变量的“别名”,和原变量共享同一块内存空间,修改引用的值,就等于修改原变量的值。

比如:

int a = 10;   // 定义变量a,值为10
int &b = a;   // 定义引用b,它是a的别名
a = 20;       // 修改原变量a
cout << b;    // 输出b:20(因为b是a的别名,所以和a的值一样)

这里,b就是a的引用,ba本质上是同一个东西。

二、引用的基本用法

1. 定义与初始化

引用必须在定义时绑定到一个已存在的变量,不能“空着”或者“临时绑定”。语法是:类型 &引用名 = 原变量;

正确示例

int x = 5;
int &y = x;   // y是x的引用,绑定成功

错误示例(初学者常犯):

int &z;       // 错误!引用必须初始化,不能未定义
int &w = 10;  // 错误!普通引用不能绑定到临时常量(10是临时变量)

2. 引用作为函数参数

当函数参数是引用时,函数内部对引用的修改会直接反映到原变量上(避免了“传值”时的拷贝开销)。

场景:交换两个变量的值

// 普通传值(会拷贝x和y的值,修改的是副本)
void swap_value(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

// 传引用(直接修改原变量x和y)
void swap_ref(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 1, y = 2;
    swap_value(x, y);  // x和y的值没变(swap_value修改的是副本)
    cout << "x=" << x << ", y=" << y << endl;  // 输出:x=1, y=2

    swap_ref(x, y);    // x和y的值被交换
    cout << "x=" << x << ", y=" << y << endl;  // 输出:x=2, y=1
    return 0;
}

关键点:传引用时,函数参数和实参直接绑定,无需额外拷贝,效率更高。

3. 引用作为函数返回值

函数返回引用时,返回的是原变量的引用,不是拷贝。但要注意:不能返回局部变量的引用(局部变量在函数结束后会被销毁,返回引用会导致未定义行为)。

正确示例:返回全局/静态变量的引用

int global = 100;  // 全局变量

int &func() {
    return global;  // 返回全局变量的引用
}

int main() {
    func() = 200;    // 修改返回的引用,即修改global的值
    cout << global;  // 输出:200
    return 0;
}

错误示例:返回局部变量的引用

int &bad_func() {
    int temp = 10;   // 局部变量,函数结束后会被销毁
    return temp;     // 错误!返回已销毁变量的引用
}

int main() {
    int &a = bad_func();  // 这里会得到垃圾值(未定义行为)
    cout << a;           // 输出可能是随机数
    return 0;
}

4. const引用(常量引用)

const修饰的引用称为“常量引用”,它有两个作用:
- 绑定临时变量(普通引用不行);
- 防止通过引用修改原变量(只读操作)。

示例1:绑定临时变量

// 普通引用不能绑定临时变量(int &c = 5; 会报错)
const int &c = 5;   // 合法!常量引用可以绑定临时变量(临时变量被存储)
cout << c;          // 输出:5

// 常量引用也可绑定表达式结果
int x = 10, y = 20;
const int &d = x + y;  // x+y是临时变量,d是它的引用
cout << d;            // 输出:30

示例2:防止修改原变量

void print(const int &a) {  // 函数参数是const引用,无法修改a
    // a = 30;  // 错误!const引用不能修改值
    cout << a;
}

int main() {
    int b = 20;
    print(b);  // 输出:20
    return 0;
}

三、引用 vs 指针:别再搞混了!

引用和指针都能实现变量的间接访问,但语法和使用场景有区别:

特性 引用(&) 指针(*)
定义 int &a = b;(必须初始化) int *a = &b;(可初始化也可不初始化)
空值 不能为null(必须绑定变量) 可以为null(int *a = nullptr;
指向变化 初始化后无法改变指向 可随时改变指向(a = &c;
解引用 无需解引用(直接用a 需要解引用(*a
语法简洁性 更直观(a = 10; 稍复杂(*a = 10;

一句话总结:引用是“变量的别名”,指针是“变量的地址”,引用更安全、更简洁,适合作为参数/返回值;指针更灵活,适合动态内存管理(如new/delete)。

四、新手必看的3个注意事项

  1. 引用必须初始化int &a; 会直接报错,必须写成 int &a = b;
  2. 别返回局部变量引用:局部变量函数结束后会销毁,返回引用会导致“野引用”。
  3. const引用的特殊用途:绑定临时变量时必须用const,否则编译报错。

五、总结

引用是C++中非常实用的特性,它让我们能更高效地操作变量。核心记住:
- 引用是变量的“别名”,和原变量共享内存;
- 传引用能避免拷贝,提高效率;
- 返回引用时注意别返回局部变量;
- const引用可绑定临时变量,且只读。

刚开始可能会觉得有点绕,但多写几个例子(比如交换函数、const引用绑定),很快就能掌握啦!下一篇我们会结合类和函数深入讲引用的高级用法,敬请期待~

Xiaoye