灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:2293回复:0

[C++技术]“指向指针的”小例子:忽然豁然开朗~

楼主#
更多 发布于:2012-09-06 11:33


之前没有碰到过这类情况,也不知道实际工程中有什么奥妙,先来一个小的测试例子看一下运行结果:
  int a = 1;
  int b = 2;  
  int *tmp = &a;
  int *p = tmp;// 第二种情况:int *;p = tmp;(此既是指向指针的)
  p = &b;
  *p = 5;

1、测试此时的a, b , *tmp, *p分别是什么: a = 1, b = 5, *tmp = 1, *p = 5;
2、如果是上述第二种情况,即指向指针的,那么这些变量又该是什么值呢?答案是:
  a = 1, b = 5, *tmp = 5, *p = 5;
  这是因为指向指针的,不仅改变了指针所指的对象,也改变了指针本身。

下面以Essential C++ P177的代码举例:
该代码是为了删除一个二叉树中等于某个值的节点:
1 void BTnode::remove_value( const int; val, BTnode *; prev ) //二叉有序树中删除节点值_val == val的节点
2 {
3     if ( val < _val ) //往左子树遍历查找
4     {
5         if ( !_lchild )
6         {
7             return; //不在此二叉树中
8         }
9         else _lchild->remove_value( val, _lchild );
10     }
11     else
12     if ( val > _val ) // 往右子树遍历查找
13     {
14         if ( !_rchild )
15         {
16             return; //不在此二叉树中
17         }
18         else _rchild->remove_value( val, _rchild );
19     }
20     else
21     { //哈哈!~找到了~就是你啦!!
22         if ( _rchild ) //看看这个要被删除的节点是否有右孩子
23         { //果然有~~有点小麻烦了~~哎
24             prev = _rchild;
25             if ( _lchild ) //要删除的节点还有左孩子~得想办法把左孩子弄到右子树下面去,这样才能删除我这个节点
26             {
27                 if ( !prev->_lchild ) //看看右子树是否有一堆左孩子
28                 {
29                     prev->_lchild = _lchild;
30                 }
31                 else BTnode::lchild_lead(_lchild, prev->_lchild);//遍历到右子树最左节点
32             }
33         }
34         else prev = _lchild;
35         delete this; //不用怕删除了本节点以后,我的孩子们连不到我的父辈节点们~~一句prev = _rchild解决了一切~~
36     }
37 }

上面代码中红色部分是最关键的地方,比如下面这棵树:




其中的null是没有节点(我这样加个null是为了让6看起来是右孩子)。
在这个图里,我要删除5节点。若函数中参数是指针,而不是指向指针的。那么上述程序,就会造成删除了5节点以后,二叉树断成两部分。(prev = _rchild;这里我们只把prev重新改变为_rchild的值,而并没有改变5这个地址所指向的值,但我们程序中这一句就要让5的地址也改变)
而如果是指向指针的,prev = _rchild;这一句就会把5这个地址赋值为6的地址,这样删除5(即delete this;)之后就不会造成二叉树的断链问题。
Essential C++ P177是这么描述的:
  为什么我们将prev以一个reference to pointer来传递呢?难道用单纯的pointer传递还不够吗?不,不够!以pointer来传递,我们能够更改的是该pointer所指之物,而不是pointer本身。为了该表pointer本身,我们必须再加一层间接性。如果将prev声明为reference to pointer,我们不但可以改变pointer本身,也可以改变由此pointer指向的对象。


喜欢0 评分0
游客

返回顶部