指针的引用未生效

000oo000 2013-02-02 11:03:17
我用visual stuido 2010 写下面二叉树的查找程序,

目的是使类中pCurrent指 针指向匹配的节点(Node<T>*),同时能发现父节点。

template<class T>
Node<T>* Tree<T>::FindNode_BSTree(Node<T>* & pNode, const T& datavalue, Node<T>* & pParent) const
{
if(pNode==NULL)
return NULL;
if(pNode->data==datavalue)
return pNode;

if(datavalue<pNode->data)
return FindNode_BSTree(pNode->pLeftChild,datavalue,pNode);
else
return FindNode_BSTree(pNode->pRightChild,datavalue,pNode);
};

查找匹配节点程序:

template<class T>
bool Tree<T>::Find_BSTree(const T& datavalue)
{
Node<T>* pParent=NULL;
FindNode_BSTree(pCurrent,datavalue,pParent);

};

查找匹配节点父节点的程序:
template<class T>
Tree<T>* Tree<T>::GetParent()
{
Node<T>* pParent=NULL;
FindNode_BSTree(pCurrent,pCurrent->data,pParent);
};

按理说,指针的引用传递参数,外层实参指针随着形参改变而改变指向的位置。
结果,最后一打印pCurrent,pParent的值,还是原来的初始值,没有改变。很是奇怪。是编译器的问题还是程序的问题?
...全文
157 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
000oo000 2013-02-03
  • 打赏
  • 举报
回复
楼上这位兄弟是c++大拿了,我想了好久,和你的结论是一样的。果真是没有生成临时变量,而层层引用,直到最后,所以对于insert函数而言,最后能实现在原来的树里真正的insert 节点效果,但实参没有跟着变。 实际一开始是被引用的概念误导了,以为引用一旦跟上一个变量,就终生不可变。永远是第一个变量的引用。其实在这种调用模式下,它只引用传给它的指针,传给什么就引用什么,如果传给别的变量,就会再下一次递归里引用这个新变量。如果多层引用同一个变量,其实就相当于都在引用一个最初的实参,是通过间接引用传递实现的。并不是每层的引用都直接引用最初的实参。 当然这有可能和C++最新标准有关,或者编译本身的实现有关,都不重要了。
lvjing_CSDN 2013-02-02
  • 打赏
  • 举报
回复
你声明为了引用,但是你好像也没有改变实参啊,我给了下你的查找函数,你参考下,看看可行:
template<class T>
Node<T>* Tree<T>::FindNode_BSTree(const Node<T>* pNode, const T& datavalue, const Node<T>* & pParent) const
{
if(pNode ==NULL || pNode->data==datavalue)
  return pNode;
pParent = pNode;
if(datavalue<pNode->data)
  return FindNode_BSTree(pNode->pLeftChild,datavalue,pParent);
else
  return FindNode_BSTree(pNode->pRightChild,datavalue,pParent);
};
000oo000 2013-02-02
  • 打赏
  • 举报
回复
假设pCurrent指向根节点,pParent指向NULL, 按理用指针的引用,执行完后pCurrent指向找到的匹配节点,pParent指向其父节点。 但用cout输出pCurrent, pParent还是原来的值。
疯狂的红豆 2013-02-02
  • 打赏
  • 举报
回复
在递归的过程中第一个参数是需要一级一级的向下伸展的,使用指针的引用是没有复制一份临时的指针,而是直接使用了pNode->pLeftChild指针域中的值,再说在程序中仅仅是查找并没有涉及到下层修改上层的指针指向的
000oo000 2013-02-02
  • 打赏
  • 举报
回复
FindNode_BSTree(pNode->pLeftChild,datavalue,pNode); 第三个参数的使用好像有点错误,抱歉,但不影响我问的问题。
000oo000 2013-02-02
  • 打赏
  • 举报
回复
但是下面这段程序, template<class T> void Tree<T>::Insert_BSTree(Node<T>* & pNode, const T& datavalue) const { if(pNode==NULL) pNode=getTreeNode(datavalue); else if(datavalue<pNode->data) Insert_BSTree(pNode->pLeftChild,datavalue); else Insert_BSTree(pNode->pRightChild,datavalue); }; 在运行结束后,一个节点的确被插进了原来的树里,但用断点跟踪的时候,用pCurrent/pRoot来调用 Insert_BSTree(Node<T>* & pNode, const T& datavalue) 在变量值那里看,pCurrent/pRoot也是未改变的,还是原值,百思不得其解,可能还未能深刻领会针指的引用的大原理。
000oo000 2013-02-02
  • 打赏
  • 举报
回复
所以,可能和编译器的机制有关,也有可能是用的不当。 用pNode->pLeftChild递归调用FindNode_BSTree(pNode,datavalue,pNode) 我的理解是pNode->pLeftChild由于是对指针的引用,所以,调用FindNode_BSTree(pNode,datavalue,pNode)的时候,没有压栈,直接调用外层实参的指针。 除非编译器在处理pNode->pLeftChild 复值给FindNode_BSTree(pNode,datavalue,pNode)中的pNode的时候,临时生成了一个指针“对象", 这样将其压栈,导致外层那个实参指针没有被实际处理。
lvjing_CSDN 2013-02-02
  • 打赏
  • 举报
回复
引用 3 楼 000oo000 的回复:
在递归调用 FindNode_BSTree(pNode->pLeftChild,datavalue,pNode) 用pNode->pLeftChild递归调用FindNode_BSTree(pNode,datavalue,pNode),相当于pNode=pNode->pLeftChild,个人认为下一次该函数的对指针的引用的时候,pNode已经指向了它的左孩子,所以……
不是这样的吧
000oo000 2013-02-02
  • 打赏
  • 举报
回复
在递归调用 FindNode_BSTree(pNode->pLeftChild,datavalue,pNode) 用pNode->pLeftChild递归调用FindNode_BSTree(pNode,datavalue,pNode),相当于pNode=pNode->pLeftChild,个人认为下一次该函数的对指针的引用的时候,pNode已经指向了它的左孩子,所以相应实参也要变化。

64,663

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧