C++ 通过引用传递表达式与通过引用传递变量
在下面显示的代码中,C++ 通过引用传递表达式与通过引用传递变量,c++,pointers,lvalue,C++,Pointers,Lvalue,在下面显示的代码中,func(a3)输入if条件并生成输出“hi”。但是,当函数的参数是表达式时,会观察到不同的行为 例如,func(a1->right)不输入if条件 #包括 使用名称空间std; 类节点{ 公众: int数据; 节点*左、*右、*父节点; 公众: 节点(int数据):数据(data){ 左=空PTR; 右=空PTR; 父项=nullptr; } ~Node(){} }; void func(节点*&节点){ 节点*p=节点->父节点; p->右=节点->左; 如果(节点->左
func(a3)
输入if条件并生成输出“hi”。但是,当函数的参数是表达式时,会观察到不同的行为
例如,func(a1->right)
不输入if条件
#包括
使用名称空间std;
类节点{
公众:
int数据;
节点*左、*右、*父节点;
公众:
节点(int数据):数据(data){
左=空PTR;
右=空PTR;
父项=nullptr;
}
~Node(){}
};
void func(节点*&节点){
节点*p=节点->父节点;
p->右=节点->左;
如果(节点->左){
cout left->parent=p;
}
节点->父节点=p->父节点;
}
int main(){
节点*a1=新节点(10);
节点*a2=新节点(20);
节点*a3=新节点(30);
节点*a4=新节点(40);
节点*a5=新节点(50);
a1->left=a2;a2->parent=a1;
a1->right=a3;a3->parent=a1;
a3->left=a4;a4->parent=a3;
a3->right=a5;a5->parent=a3;
/*
a1
/ \
a2 a3
/ \
a4 a5
*/
/*案例1:打印hi*/
func(a3);
/*案例2:不打印hi*/
//func(a1->右);
/*案例3:打印hi*/
//节点*ptr=a1->右侧;
//func(ptr);
}
我有两个问题:
(gdb) b 17
Breakpoint 1 at 0x555555554856: file pointer_ref.cpp, line 17.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, func (node=@0x555555767e80: 0x555555767ed0) at pointer_ref.cpp:18
18 Node* p = node->parent;
(gdb) p node->data
$1 = 30 // a3
(gdb) n
19 p->right = node->left;
(gdb) p p->data
$2 = 10 // a1
(gdb) n
20 if (node->left) {
(gdb) p p->right->data
$3 = 40 // a4
**(gdb) p node->left->data
Cannot access memory at address 0x0**
// ^^^ This seems to be the problem location
// After changing p->right to node->left,
// somehow, node->left becomes null
(gdb) p node->left
$4 = (Node *) 0x0
(gdb)
您已将引用传递到
a1->right
。因此,对该字段所做的任何更改都可以在该函数中看到。p->右=节点->左
实际上将a1->right
设置到不同的节点
在案例3中,您将引用传递给一个局部变量ptr
,该变量不会被更改,因为它是一个副本
如果您添加:
cout
将表达式引用传递给func而不是变量引用时出现不同行为的原因
原因是程序中复杂的逻辑。在这种特殊情况下,当您传递a3
或a1->right
时,任一指针都指向同一个对象,但func()
本身会修改a1->right
,因此,当引用传递a3
时,更改不会影响节点
,但当传递a1->right
时会影响。亨斯发现了差异
将表达式引用传递给函数的惯用方法是什么
按您的方式传递引用并没有问题,问题是数据关系过于复杂。例如,在您的情况下,没有理由通过引用传递此指针。作为旁白,不要包含位/stdc++.h
,因为它带来了所有东西,而您只想带来一些东西。注意@AndyG。我现在看到了问题。您应该使用调试器逐步完成此操作,并观察树的外观。我要说的是,没有理由在func
中通过引用接收您的ptr。您可以修改传入的内容。因此,它可能与进行不同函数调用的顺序有关。通过引用传递指针的原因是什么?除了使代码过于复杂之外。那么为什么node->left变为null(请参考新包含的gdb输出)。node->left
变为null,因为node
现在指向另一个没有left-chidl的节点。a1->右侧是a3,所以节点->左侧是a3->左侧,此时为a5。a5->left为空。(我希望我没有弄错)