C++中的引用

引用,用途是对变量取别名,本质是一个指针常量。

1.初始化

&写在左侧为引用,写在右侧为取地址,引用用法:Type &别名 = 原名。

1 void test01(){
2     int a = 10;
3     int &b = a;
4     b = 20;
5     cout << a << " " << b << endl;
6 }

引用必须初始化,另外初始化后不能再修改指向其他变量

1 void test02(){
2     //int &a; //报错error C2530:引用必须初始化
3     int a = 10;
4     int &b = a;
5     int c = 20;
6     //int &b = c; 不能修改初始化的指向,会报错重定义
7     b = c;
8 }

对数组起别名

 1 void test03(){
 2     //第一种方式
 3     int a[10];
 4     for (int i = 0; i < 10; ++i){
 5         a[i] = i;
 6     }
 7     int(&arr)[10] = a;
 8 
 9     //第二种方式,通过typedef
10     typedef int(INTARR)[10];
11     INTARR &myAr = a;
12 }

2.参数传递方式

引用传参和地址传参的作用是一样的,都是为了修改变量值,其中引用后面的a和b相当于地址传参中的*a和*b。

 1 void swap01(int *a, int *b){
 2     //----------
 3     //int c = 0;
 4     //int *temp = &c;  5     //*temp = *a;
 6     //*a = *b;
 7     //*b = *temp;
 8     //----------
 9     int temp = *a;
10     *a = *b;
11     *b = temp;
12     cout << *a << " " << *b << endl;
13 }
14 
15 void swap02(int &a, int &b){
16     int temp = 0;
17     temp = a;
18     a = b;
19     b = temp;
20     cout << a << " " << b << endl;
21 }

3.使用注意事项

(1)引用必须引一块合法的内存空间,也不是引用NULL

(2)不要返回局部自动变量的引用

 1 int  &test04(){
 2     //int &a = 10;
 3 
 4     //------------
 5     //int c = 10;
 6     //int &b = c;
 7     //return b;
 8     //------------
 9 
10     int a = 10;
11     return a;
12 }

第2行显示了引用一块非法的内存空间,4-8行和10-11行是返回局部变量的引用,这种返回值可能会因为编译器的优化,使得第一次可以成功返回,但多返回几次就会报错。

(3)函数的返回值为引用,这个函数调用可以作为左值

int main(){
	
	test04() = 20; //相当于a = 20
	int a = test04();
}

 4.引用的本质 

引用的本质是指针常量。

1 Type &ref = val; //Type *const ref = &val
2 
3 int a = 10;
4 int &b = a;//自动转换为int *const b = &a,指针常量必须初始化,因此引用必须初始化
5 b = 20; //内部发现b是引用,自动帮我们转换:*b = 20;

5.指针引用 

一般的二级指针 Type **p可以改写成Type *&p

 1 #include <iostream>
 2 using namespace std;
 3 
 4 struct Person{
 5     int age;
 6 };
 7 
 8 void allocMemory(Person **p){
 9     *p = (Person*)malloc(sizeof(Person));
10     (*p)->age = 100;
11 }
12 
13 void test05(){
14     Person *p = NULL;
15     allocMemory(&p);
16     cout << p->age << endl;
17 }
18 
19 void allocMemoryRef(Person *&p){
20     p = (Person*)malloc(sizeof(Person));
21     p->age = 200;
22 }
23 
24 void test06(){
25     Person *p = NULL;
26     allocMemoryRef(p);
27     cout << p->age << endl;
28 }
29 
30 int main(){
31     
32     test05();
33     test06();
34     system("pause");
35     return 0;
36 }

6.常量引用 

通过一个例子引入常量引用

1 void test(){
2     //int &a = 10; // 引用不合法的空间
3     const int &a = 10; //会分配内存,编译器进行处理 int tmp = 10; const int &a = tmp;
4     int *p = (int *)&a;
5     *p = 100;
6     cout << a << endl; //a被修改
7 }

其实上面的代码使用的比较少,一般多用const Type &ref进行形参使用,使用常量引用形参的好处:(1)使用引用作为形参,不会产生新的变量,减少形参和实参传递的开销;(2)使用引用可能会导致实参随着形参的改变而改变。声明为const之后就会消除这种副作用。

原文地址:https://www.cnblogs.com/qinguoyi/p/10206110.html