写在前面:引用和指针有着很大的区别,引用指针其实非常有用
首先举个例子:
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; }
|
运行下来发现变量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; }
|
可以发现指针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>
void ChangeByRefer(int &b) { b = 2; }
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;
a = 1; ChangeByRefer(b); std::cout << a << std::endl; }
|
如果需要用一个函数以无返回值的方式初始化一个指针所指向的结构体时,用引用就方便多了
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;
void InitNewTreeByRefer(BiTree &t, int data) { t = new BiTNode{}; t->data = data; t->lchild = t->rchild = nullptr; std::cout << &t << std::endl; std::cout << t << std::endl;
}
int main() { BiTree tree; InitNewTreeByRefer(tree, 2); std::cout << &t << std::endl; std::cout << t << std::endl; }
|
这里直接对指针tree
所存放的地址进行操作,在函数中将一个新的地址赋给它
主函数中指针tree
和字函数中指针t
都是同一个指针地址0x7ffee704e198
的别称,这个地址中存放的就是new BiTNode{}
的地址0x7f8c5bc02910