一. 概念介绍
1. 引用的概念 :
引用变量是一个别名,也就是说,它是某个 已存在变量 的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或 变量名称 来指向变量
引用可以认为是一个变量的另一个外号, 这个外号可以呼唤到原变量
而且在C++中,使用 & 符号可以创建变量的引用, 它指向同一块内存地址上的变量. 通过引用,可以直接操作原始变量,并且对引用的修改会反映在原始变量上. 这样可以避免复制大型数据结构或对象并提高性能.
2. 引用& vs 指针*
区别 :
-
不存在空引用, 引用必须指向到一块合法的内存, 而指针可以为空指针
-
一旦引用被初始化为一个对象,就不能被指向到另一个对象。
而指针可以在任何时候指向到另一个对象.
类似于引用声明的变量, 更像const指针申明的变量
例 :
//va 引用 a:相当于 va 借用了 a 的内存地址和值,a 和 va 任意一个发生改变的话 a和va 同时改变。指针 va 指向 a:va 借用了 a 的值,但是va的内存地址重新分配,不同于 a
//代码1
int a = 10;
int& va = a;
//代码2
int a = 10;
int* const pa = &a;
//其中代码一和代码二中的引用和指针情况相似, 指针指向的空间固定, 引用指向的变量固定.都可以通过指针和引用改变变量, 但不能改变指针和引用指向的位置
;
- 引用必须在创建时被初始化。指针可以在任何时间被初始化
**错误案例**
int a = 10;
//声明引用,旦未初始化
int &va;
va = a;
//直接无法运行, 编译器标红
**正确案例**
int& va = a;
二. 引用的创建
1. 常用的的引用
语法 :
可以大概认为为 : 类型& 引用名 = 被引用名
例 :
int j = 10;
int& vj = j;
在这些声明中, & 读作引用 因此,该案例中的声明可以读作 vj 是一个初始化为 j 的整型引用
此时vj相当于借用了j的内存地址和值, 其中两者的任何一个发生改变, 另一个变量也会同时改变.
2. 数组的引用
语法 :
数组类型& 数组引用名 = 被引用的数组名
特点 :
数组的引用时一定要填入数组的大小
int arr[] = { 1,2,3,4 };
int(&t)[4] = arr;//左右参数的类型需要对应,也就是 int(&)[4] 与 int[4], 中括号中的数字也需要相同
cout << t << endl;
3. 结构体引用
语法 :
结构体类型& 结构体引用名 = 被引用的结构体名
例 :
typedef struct Coor
{
int x;
int y;
}Coor;
struct Point
{
int x;
int y;
};
Coor c1; //定义一个结构体变量,叫c1.
Coor& c2 = c1; //给c1起了一个别名叫c2.
c2.x = 10; //通过引用给结构体变量的数据成员赋值
c2.y = 20;
cout << c1.x << ' ' << c1.y << endl; //输出的结果:10 20
struct Point p1;
struct Point& p2 = p1;
p2.x = 1; p2.y = 2;//通过p2改变p1
cout << p1.x << ' ' << p1.y << endl;
4. 指针类型的引用
语法 :
指针类型& 指针引用名 = 指针名
此处指针类型为 类型* (如: int*)
int a = 10; //定义一个整型的a变量,a的值为10
int *p = &a; //定义一个指向a变量的指针
int*& q = p; //定义一个指针的引用,即q为p的别名
*q = 20; //把20赋给*q,相当于是把20赋值给*p,也就相当于把20赋值给a.
cout<< a << endl; //输出a 的值为20.
5. 作为函数参数
曾经传入函数时, 我们传入的值会在临时变量中, 修改临时变量对外部变量没有影响. 若想产生影响, 则需要传入地址, 并用指针接收. 现在可以传入变量本身, 用引用接收.
例 :
void swap1( int* a,int* b) //形参为两个整型的指针变量
{
int c = 0;
c = *a;
*a = *b;
*b = c;
}//从前, x,y交换的函数
void swap2 (int& a, int& b) //形参为两个整型的引用
{
int temp = 0;
temp = a;
a = b;
b = temp;
}//现在
int x = 10,y = 20;
swap1(&x, &y);
cout << x << ' '<< y << endl;
swap2(x, y);
cout << x << ' '<< y << endl;