指针 & 引用

一、引用

引用是一种复合类型,它允许一个变量,也就是引用,成为另一个变量的别名。
引用和原变量访问同一内存,通过引用访问时,实际就是在访问该变量原本的数据。

1. 定义引用

数据类型 &name = 变量;
// 数据类型和被引用变量的数据类型相同

int a = 100;
int &b = a;

b = 200; // b 是 a 的引用,修改 b 就是修改 a

2. 高频考点

  • 引用不是新定义一个变量,而是给已存在的变量起一个别名。
  • 引用在定义时必须初始化,不存在空引用。
  • 引用通常不占用额外的可访问内存空间,它和被引用的变量共享同一块内存地址,具体由编译器实现。
  • 引用一旦初始化后,就不能再绑定到其他变量上。

二、指针

指针是一种特殊的变量,它存储另一个变量的地址,而不是直接存储数据。
使用指针可以直接访问和操作其指向内存地址中的值。

1. 声明指针

数据类型 *p; // 指针变量的类型是 数据类型*

int* p;      // 声明了一个指针,并没有初始化,是野指针
int *p;

2. 定义指针

数据类型 *p = &变量;
// 数据类型和被指向变量的数据类型相同

int a = 100;
int *p = &a;       // 取地址符 & 获取变量 a 的地址,赋值给指针变量

int *p2 = nullptr; // 定义一个空指针,值为 nullptr 或 NULL

3. 解引用

解引用用于访问指针变量所指向内存地址的值。
指针变量存储了原变量地址,可以通过 * 来访问该地址存储的数据。

cout << *p; // 访问变量 a 内存地址中的值,输出
*p = 200;   // 修改变量 a 内存地址中的值,赋值为 200

4. 指针的运算

指针可以进行加法和减法运算,通常用于数组操作。

5. 指针的动态内存分配

使用 new 和 delete 运算符进行动态内存分配和释放。

int *p = new int; // 分配内存并返回地址给 p
delete p;         // 释放内存
p = nullptr;      // 避免野指针

三、指针和引用的区别

特性引用指针
定义与初始化必须初始化,绑定到一个变量可以先声明后初始化,可指向 NULL
重新绑定一旦绑定不可更改引用的变量可随时指向其他变量
内存占用通常不占用额外内存,编译器层面占用内存,存储变量地址
操作方式直接使用,不需要解引用需通过 * 解引用访问变量
空值无空引用,必须绑定有效变量有空指针,NULL 或 nullptr
安全性较高较低,有野指针、空指针可能性
语法复杂度简单较复杂,需要手动管理地址