本篇主要介绍C++ 中的引用。

什么是引用

引用实际上不是一种独立的数据类型,类似于 C 中的指针,本质就是对变量起别名,例如:

int a = 66;
int& b = a;// 表示给变量 a 起别名为 b
/*
&b : 取地址
1&2: 按位与
*/
b++;// b = 67  a = 67
int& c = b;// c = 67

引用和指针的比较

  • 引用必须初始化,指针可以不初始化
int& b; // 错误,必须初始化
int* p; // 野指针
  • 引用不可以为空,指针可以为空
int& a = NULL; // 错误
int* p = NULL;

关于这一点需要注意:

// 常引用
const int& a = NULL; // 实际上相当于 0
const int& b = 20;
  • 引用不可以更换目标,指针可以
int a = 66;
int& b = a;

int m = 118;
b = m; // 这里相当于赋值,m 的值给 a 了

int* p = &a;
p = &m;
  • 不能声明引用型数组,可以声明指针型数组
int data[5]; // 整型数组
int* data[5]; // 指针数组
char data[5]; // 字符数组
int& data[5];// 引用数组 错误

引用和指针的使用说明

  • 指针中的*停靠问题
int* p;
int * p;
int *p;
// 上面三种方法都是可以的

int* p,*q;
int *p,*q;
// 效果等价
  • 引用中&的停靠问题
int a = 66;
int& b = a;
int & b = a;
int &b = a;
int &r = a,&m = a;
// 同样没有什么区别
  • 当定义多个指针/引用时,可以起别名
int *p,*q,*r;
typedef int* PINT;
PINT p,q,r; //定义三个指针

typedef int& RINT;
int b,d;
RINT a = b,c = d;
  • 可以定义指向指针的指针,但是不可以定义指向引用的指针
int a = 66;
int& b = a;
int* pa = &a;

int** pa = &pa;
int&* pa = &b; // 错误 指向引用的指针
  • 可以定义引用指针的引用,不可以定义引用引用的引用(可以给指针定义引用,不可以给引用定义引用)
int a = 66;
int& b = a;
int* pa = &a;

int*& pb = pa;// 指针的引用
int&& c = b; // 错误
  • 可以定义指针数组,但是不能定义引用数组,可以定义数组的引用 ```cpp int data[5]; //整型数组 int* data[5]; //指针数组 int& data[5]; //引用数组 错误

int (*p)[5]; // 数组指针 int (&p)[5]; // 数组引用 ```

引用作为函数的形参

  • 引用作为函数的形参,能够修改实参的值

  • 引用作为函数的形参,可以避免参数传递过程中数据的拷贝

  • 通过将参数定义为常引用,防止在函数内部对实参做修改,同时还可以接受常量型实参

  • 引用作为形参,实际上就是址传递

引用作为函数的返回值

永远不要返回局部变量(包含函数的形参)的引用,可以返回静态局部变量/全局变量/动态内存/实参/结构体的成员的引用,这样是安全的。