C++学习笔记——引用

引用作为c++的一个重要功能,起到了不可忽视的作用,那么,就让我们一起来看看吧!

1 引用的基本使用

  • 作用:给变量起别名
  • 语法数据类型 &别名 = 原名
  • 注意:引用的数据类型要和原类型一样

原理图:
在这里插入图片描述
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>

using namespace std;


int main() {

int a = 10;
//创建引用
int &b = a;
cout << "a = " << a << endl;
cout << "b = " << b << endl;

b = 100;
cout << "a = " << a << endl;
cout << "b = " << b << endl;

system("pause");
return 0;
}

2 引用的注意事项

  • 引用必须初始化
  • 引用在初始化后,不可以改变

原理图:
在这里插入图片描述
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int  main() {
int a = 10;

//1、引用必须初始化
int &b=a;//错误,必须要初始化

//2、引用在初始化后,不可以改变
int c = 20;
b = c;//赋值操作,而不是更改引用,即这里只是把b指向的内置赋值成20

cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "b = " << b << endl;

system("pause");
return 0;
}

3 引用做函数参数

  • 作业:函数传参时,可以利用引用的技术让形参修饰实参
  • 优点:可以简化指针修改实参

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//交换函数
//1、值传递
void mySwap01(int a, int b) {
int temp = a;
a = b;
b = temp;
//cout << "mySwap01 a = " << a << endl;
//cout << "mySwap01 b = " << b << endl;
}
//2、地址传递
void mySwap02(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;

}
//3、引用传递
void mySwap03(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}

int main() {
int a = 10;
int b = 20;
//mySwap01(a, b);//值传递,实参不会改变
mySwap02(&a, &b);//地址传递,实参会改变
mySwap03(a, b);//地址传递,实参会改变
cout << "a = " << a << endl;
cout << "b = " << b << endl;

system("pause");
return 0;
}

总结:通过引用参数产生的效果同地址传递是一样的。引用的语法更清楚简单

4 引用做函数返回值

作用:引用是可以作为函数的返回值存在的

注意:不要返回局部变量的引用
用法:函数调用作为左值

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//引用做函数的返回值
//1、不要返回局部变量的引用
int& test01() {
int a = 10;//局部变量存放在四区中的栈区
return a;
}

//2、函数的调用可以作为左值
int& test02() {
static int a = 10;//静态变量,存放在全局区,全局区上的数据在程序结束后由系统释放
return a;
}


int main() {

int &ref = test01();

//cout << "ref = " << ref << endl;//第一次结果正确,是因为编译器做了保留
//cout << "ref = " << ref << endl;//第二次结果错误,是因a的内存已经释放

int &ref2 = test02();
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;
test02() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;


//这个就不是变量的引用了,这里相对于直接在新的内存copy函数的返回值
int ref3 = test02();
cout << "ref3 = " << ref3 << endl;
cout << "ref3 = " << ref3 << endl;
test02() = 999;
cout << "ref3 = " << ref3 << endl;
cout << "ref3 = " << ref3 << endl;
cout << "ref3 = " << ref3 << endl;

system("pause");
return 0;
}

5 引用的本质

本质:引用的本质在c++内部实现是一个指针常量,即指针的指向不可以修改,指针指向的值是可以修改的

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//发现是引用,转换为int* const ref = &a;
void func(int &ref) {
ref = 100;//ref是引用,转换为*ref = 100;
}

int main() {

int a = 10;

//自动转化为int *const ref = &a;指针常量是指针的指向不可以改,也说明为什么引用不可更改
int &ref = a;
ref = 20; //内部发现ref是引用1,自动帮我们转换为:*ref = 20;

cout << "a = " << a << endl;
cout << "ref = " << ref << endl;

func(a);

system("pause");
return 0;
}

原理图:
在这里插入图片描述

结论:C++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了

6 常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//打印数据
void showValue(const int &val) {//加上const就不能修改了
//val = 1000;
cout << "val = " << val << endl;
}

int main() {
//常量引用
//使用场景:用来修饰形参,防止误操作
//int a=10;
//int &ref = 10;//错误,引用必须引一块合法的内存空间,可以是栈区,也可以是堆区,所以这里字面量是不可以的
const int &ref = 10;//加上const之后,编译器将代码修改为 int temp = 10; const int &ref = temp;
//ref = 20;//加入const之后变为只读,不可以修改

int a = 100;
showValue(a);
cout << "a = " << a << endl;


system("pause");
return 0;
}