C++引用

2

C++引用

  从今天开始,正式进入C++的内容中,引用时C++的代码风格,为了使代码简单清晰,C++引入了引用这个概念。为什么要引入呢?因为人们发现用指针指来指去,非常复杂,而且容易出错,所以提出了一种更加简单的形式。引用可以看成是起别名,就像小名一样,小伙伴们应该都有小名,在家里一般不会直呼其名,常常会给小孩子起一个小名。那么小名就是你,大名也是你,因此对小名进行操作时,相当于对这个变量进行了操作。

引用的定义

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
#include<iostream>
using namespace std;

int main() {

//引用的定义就是在变量名前加一个取地址符&,并且让其等于另一个变量,相当于给一个变量又起了一个小名
//注意只能让一个变量名传给引用的数据类型,不可以是常量。而且引用只能在创建时进行赋值,不可以先创建然后再赋值。
int a = 10;
int& b = a;
int& c = b;

//我们可以看出,它们a,b,c变量具有相同的地址值,而且数据变化时,它们三个具有相同的变化。
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "&a = " << &a << endl;
cout << "&b = " << &b << endl;
cout << "&c = " << &c << endl;

b = 20;

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

c += 10;

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

return 0;
}

1

引用本质的探寻

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
#include <iostream>
using namespace std;

struct Student
{
int a = 10;
int& b = a;
int c = 20;

//定义两个变量a和c,定义a的引用b,由先前的知识可以知道a和b具有相同的地址,c的地址和a不同。
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "&a = " << &a << endl;
cout << "&b = " << &b << endl;
cout << "&c = " << &c << endl;

//让c的值赋值给b会出现什么神奇现象呢?是b和c具有相同的地址?还是a和b具有相同地址?还是a,b,c都具有相同的地址呢?
b = c;

//原来a和b仍然具有相同的地址,a和c的地址不同。这是什么原因呢?
//我们在指针部分讲解了常量指针和指针常量。这里b的值可以改变,但是b和a绑定了,b只能指向a,不能改变其指向。这种我们称之为指针常量。
//引用本质就是指针常量,只不过我们隐藏了指针的定义和写法,更加简单。
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "&a = " << &a << endl;
cout << "&b = " << &b << endl;
cout << "&c = " << &c << endl;

return 0;
}

2

引用作为函数参数

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
43
44
45
46
#include<iostream>
using namespace std;

void swap(int& a, int& b) {

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

int temp = a;
a = b;
b = temp;

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

int main() {

int a = 10;
int b = 20;

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

//既然引用的本质是一个指针,那么必然满足地址传递的性质,所以在函数内部操作会影响到外部变量的值。
//给小伙伴讲解一下调用函数背后的操作,首先将a和b的值传入函数列表,然后在函数参数中执行int& a = a,int& b = b
//后面的a和b是实参,前面的a和b是形参,此时形参a就是实参a的小名,那么对小名a操作就等价于对大名a操作,所以外部的值会发生改变。
swap(a, b);

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

return 0;
}

4

new和delete

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
#include<iostream>
using namespace std;


int main() {

int a1 = 10;
int a2 = 20;

//栈区:由编译器自动分配释放,存放函数的参数,局部变量等。
//堆区:由程序员分配和释放,最后由操作系统进行回收。
//在函数中的局部变量,不要返回其地址,因为函数调用结束后,会由编译器自动释放,会导致异常。
//在堆区的数据由程序员分配和释放,分配的方式是使用new关键字,并返回开辟的地址,释放的方式是使用delete关键字。
//如果开辟或释放数组则要使用中括号进行说明,new 数据类型[], delete[]。
int* b1 = new int(10);
int* b2 = new int(20);
int* c1 = &a1;
int* c2 = &a2;

//可以看出b1,b2的地址非常接近,在一个区内,c1和c2的地址也非常接近,也在同一个区内。但是b1和c1的地址却不在同一个区,这就是堆区和栈区的区别。
cout << "b1 = " << b1 << endl;
cout << "b2 = " << b2 << endl;
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;

delete b1;
delete b2;

return 0;
}

C++小结

  引用是C++中的重要工具,在C++中推荐使用引用代替指针来传递参数,因为操作简单,使用方便,所以小伙伴们务必记住它。

-------------本文结束感谢您的阅读-------------
0%