程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> “指向指針的引用”小例子:忽然豁然開朗~

“指向指針的引用”小例子:忽然豁然開朗~

編輯:C++入門知識

之前沒有碰到過這類情況,也不知道實際工程中有什麼奧妙,先來一個小的測試例子看一下運行結果:
  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指向的對象。

 摘自 ziyoudefeng
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved