目录

 

一、什么是引用?

 生活中的理解

二、引用的定义方式

 基本语法

三、引用的本质理解

 运行结果特点

四、引用的特性

 1. 引用必须初始化

 错误写法

✔ 正确写法

 2. 一个变量可以有多个引用

 3. 引用一旦绑定,不能修改指向

 真正发生的是

 原因

五、引用的核心用途

六、引用传参

 传统交换函数(C语言)

 C++引用版本

 调用方式

 优势

七、引用在数据结构中的使用

八、引用修改结构体

 好处

九、引用作为返回值

 为什么返回引用?

 如果不返回引用

 返回引用后

十、引用替代二级指针

 使用引用后

 好处

十一、const引用

 1. const对象必须用const引用

 错误写法

✔ 正确写法

 2. const引用可以引用普通对象

 原因

十二、临时对象与const引用

 为什么必须加const?

 所以只能:

十三、什么是临时对象?

十四、引用和指针的区别

 相同点

 不同点

引用

指针


一、什么是引用?

在 C++ 中,引用(Reference)并不是新定义一个变量,而是:

给已经存在的变量取一个“别名”。

也就是说:

  • 引用和原变量使用的是同一块内存空间

  • 修改引用,其实就是修改原变量

  • 编译器不会额外开辟空间


 生活中的理解

例如:

  • 李逵 → “铁牛”

  • 李逵 → “黑旋风”

虽然名字不同,但本质上还是同一个人。

引用也是一样:

int a = 10;
int& b = a;

这里:

b

只是:

a

的另一个名字。


二、引用的定义方式

 基本语法

类型& 引用名 = 引用对象;

例如:

int a = 0;
int& b = a;

三、引用的本质理解

来看下面代码:

#include<iostream>
using namespace std;

int main()
{
    int a = 0;

    int& b = a;
    int& c = a;
    int& d = b;

    ++d;

    cout << &a << endl;
    cout << &b << endl;
    cout << &c << endl;
    cout << &d << endl;

    return 0;
}

 运行结果特点

会发现:

a、b、c、d 的地址完全相同

说明:

引用本质上就是同一个变量的多个名字。


四、引用的特性


 1. 引用必须初始化

引用在定义时必须绑定对象。


 错误写法

int& ra;

因为引用必须明确“引用谁”。


✔ 正确写法

int a = 10;
int& ra = a;

 2. 一个变量可以有多个引用

int a = 10;

int& b = a;
int& c = a;
int& d = a;

这些都是:

a

的别名。


 3. 引用一旦绑定,不能修改指向

例如:

int a = 10;
int& b = a;

int c = 20;

b = c;

很多人以为:

b 改为引用 c

实际上并不是。


 真正发生的是

a = c;

即:

把 c 的值赋给 a。


 原因

因为:

C++引用不能重新绑定对象。


五、引用的核心用途

引用最常见的用途:

  • 引用传参

  • 引用返回值


六、引用传参


 传统交换函数(C语言)

C语言通常需要:

Swap(int* px, int* py)

需要传地址。


 C++引用版本

void Swap(int& rx, int& ry)
{
    int tmp = rx;
    rx = ry;
    ry = tmp;
}

 调用方式

int x = 0;
int y = 1;

Swap(x, y);

 优势

相比指针:

✔ 调用更简单
✔ 不需要取地址
✔ 可读性更高
✔ 更接近普通变量使用方式


七、引用在数据结构中的使用

很多数据结构教材会大量使用引用。

目的:

替代复杂指针传参,简化代码。


八、引用修改结构体

例如栈初始化:

void STInit(ST& rs, int n = 4)

这里:

rs

实际上就是:

st

本身。


 好处

函数内部修改:

rs.top

实际上就是修改:

st.top

九、引用作为返回值

来看代码:

int& STTop(ST& rs)
{
    return rs.a[rs.top];
}

 为什么返回引用?

因为:

STTop(st1) += 10;

需要直接修改栈顶元素。


 如果不返回引用

返回的是临时值:

修改不了原数据

 返回引用后

相当于:

直接返回原对象本身

因此可以直接修改。


十、引用替代二级指针

链表中经常需要:

LTNode**

很多人觉得很复杂。


 使用引用后

void ListPushBack(PNode& phead, int x)

这里:

PNode&

其实就是:

LTNode*&

即:

“指针变量的引用”


 好处

这样就不需要:

二级指针

代码更容易理解。


十一、const引用


 1. const对象必须用const引用

例如:

const int a = 10;

 错误写法

int& ra = a;

因为:

普通引用会导致权限放大。


✔ 正确写法

const int& ra = a;

 2. const引用可以引用普通对象

int b = 20;

const int& rb = b;

这是允许的。


 原因

因为:

权限可以缩小,但不能放大。

注:虽然rb不能修改,但是b可以修改,rb权限变了不代表b的权限变了


十二、临时对象与const引用

来看代码:

const int& rb = a * 3;

 为什么必须加const?

因为:

a * 3

会产生:

临时对象

而 C++规定:

临时对象具有常性。


 所以只能:

const int&

来引用。


十三、什么是临时对象?

临时对象:

编译器为了保存表达式结果而临时创建的匿名对象。

例如:

a * 3

结果不会立刻消失,而是暂时保存。

这个保存结果的对象就是:

临时对象

注:常见的临时对象有:表达式,隐式类型转换(如将一个int变量赋值给一个double变量)


十四、引用和指针的区别


 相同点

  • 都能间接访问对象

  • 都能修改对象


 不同点

引用

✔ 必须初始化
✔ 不能改变绑定
✔ 使用更方便


指针

✔ 可以为空
✔ 可以改变指向
✔ 更灵活

更多推荐