由一道牛客网《剑指offer》的编程题引发的思考,题目如下:
二叉搜索树与双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中结点指针的指向。
按照递归的解题思路,有如下解答:
1 | /* |
代码中23行使用了TreeNode*& prenode
,这里,如果缺少了&
,则结果会出错!
以下,对C++中*、&、*&以及&* 四种形式展开讨论。
* 代表指针
& 代表引用、别名
指针和引用的区别之一:
参数传递时,不管是传值还是传指针,函数都会产生一个临时副本变量,但在传引用时,不会生成临时变量。
*& 首先是一个指针,然后前面的&代表是这个指针的引用。 指针的引用其实就是指针的一个别名,和指针具有相同的地址。
&* 首先是一个变量的引用,然后是指向这个引用的指针,但是,因为引用不是对象,没有实际的地址,因此 不能定义指向引用的指针 。
问题:向函数中传递指针和传递指针的引用的区别
如果传递的是指针,那么会先复制该指针,在函数内部使用的是复制后的指针,这个指针与原来的指针虽然指向相同的地址,但是如果在函数内部将复制后的指针指向了另外的地址,那么不会影响原来的指针。
但是对于传递指针的引用,如果将传递进来的指针指向了新的地址,那么原始的指针也会指向新的地址,这也是为什么在该题中,必须使用指针的引用,而不能使用指针的原因。就是因为在这段代码中,要对指针指向的值进行更改,而在递归的函数中,又需要保证prenode指向的值保持统一,因此,必须使用指针的引用来使在不同层的递归函数中,prenode指向的值都是一样的。
在传递指针的引用时,还有另外一个问题,那就是如果由于原始的指针不再指向原始对象了,所以如果没有其他指针指向该原始对象的话,就会造成内存泄漏。同理,如果在函数内释放了指针的引用,那么在函数外部就不能在使用原来的指针了,因为原来的内存已经被释放了。