c++中的引用

写在前面:引用和指针有着很大的区别,引用指针其实非常有用

首先举个例子:

1
2
3
4
5
6
7
8
#include <iostream>
int main() {
int a = 1;
int &b = a;
a = 2;
std::cout << &a << " " << &b << std::endl;
// 0x7ffeed5d117c 0x7ffeed5d117c
}

运行下来发现变量a和b所拥有的地址是相同的,这个地址0x7ffeed5d117c有两个别名:a,b;也就是说对b修改其值也会把地址0x7ffeed5d117c中的值修改掉,这样子a的值也会改变


这个特性好像和指针有点像呀

1
2
3
4
5
6
7
#include <iostream>
int main() {
int a = 1;
int *a_ptr = &a;
std::cout << &a << " " << a_ptr << " " << &a_ptr << std::endl;
// 0x7ffeeb39e19c 0x7ffeeb39e19c 0x7ffeeb39e190
}

可以发现指针a_ptr存放的是变量a的地址0x7ffeeb39e19c*a_ptr就是改地址存放的值,达到和修改前面a的引用b相同的效果

但是,这个指针a_ptr是开辟了一个新的地址空间0x7ffeeb39e190来存放a的地址0x7ffeeb39e19c的,而引用b是直接指向a的地址,并没有开辟一个新的地址空间存放,这也许就是指针和引用最大的不同

所以,以下两个字函数的都可以达到修改a的值的效果

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
#include <iostream>
/**
* 2018/7/31
* 根据引用修改
*/
void ChangeByRefer(int &b) {
b = 2;
}

/**
* 2018/7/31
* 根据指针修改
*/
void ChangeByPointer(int *b) {
*b = 2;
}

int main() {
int a = 1;
int *a_ptr = &a;
int &b = a;

ChangeByPointer(a_ptr);
std::cout << a << std::endl;
// 2

a = 1;
ChangeByRefer(b);
std::cout << a << std::endl;
// 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
#include <iostream>

typedef struct BiTNode {
int data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

/**
* 2018/7/31
* 以引用方式初始化
*/
void InitNewTreeByRefer(BiTree &t, int data) {
t = new BiTNode{};
t->data = data;
t->lchild = t->rchild = nullptr;
std::cout << &t << std::endl;
// 0x7ffee704e198
std::cout << t << std::endl;
// 0x7f8c5bc02910

}

int main() {
BiTree tree;
InitNewTreeByRefer(tree, 2);
std::cout << &t << std::endl;
// 0x7ffee704e198
std::cout << t << std::endl;
// 0x7f8c5bc02910
}

这里直接对指针tree所存放的地址进行操作,在函数中将一个新的地址赋给它

主函数中指针tree和字函数中指针t都是同一个指针地址0x7ffee704e198的别称,这个地址中存放的就是new BiTNode{}的地址0x7f8c5bc02910