在做一些基于二叉搜索树的问题时...我在函数调用中遇到了一些困惑:
void find(node* root,node*& temp)
{
blah blah...
}
int main()
{
node* temp=NULL;
node* root=NULL;
find(root,temp);
}
两个传递的参数之间有什么区别?
答案 0 :(得分:2)
在
dispatch_sync(dispatch_get_main_queue(), ^{ // handle error or segue }
void find(node* root,node*& temp)
按值传递。您对root
所做的任何操作都会反映在来电者中,但对*root
的任何更改都不会。
root
通过引用传递。您对temp
所做的任何操作都将反映在来电者中,对*temp
的任何更改也会反映在来电者中。
答案 1 :(得分:2)
node *root
表示指向node
结构的指针(按值传递)。如果更改该值,则在此处更改本地可更改值。
node *&temp
表示对指向node
结构的指针的引用。如果更改temp
的值,则修改引用传递的原始指针。
答案 2 :(得分:0)
第一个指针函数参数(即node *root
)按值传递(即原始指针对象的副本在函数中传递)和第二个(即node*& temp
)通过引用传递(即,在函数中传递原始指针的别名)。
考虑以下示例:
void find(node* root,node*& temp) {
root = z;
temp = z;
}
int main() {
node *root = x;
node *temp = y;
find(root, temp);
// at this point root still points to x
// temp changed and points to z
}
答案 3 :(得分:0)
声明的标识符上的&
前缀使其成为引用。因为引用不是const,所以参数表达式必须是左值(即必须指定一个对象)。该函数可以修改该对象!
如果函数没有修改对象而你没有尝试传递非对象的东西,比如空指针常量,你就不会发现任何差异。
声明的类型不会改变;无论哪种方式,类型都是node *
。引用不是类型;它是名称如何引用价值的一个方面。
例如,如果我们有:
int x = 0, y = 2;
有两个对象。如果我们将y
声明为引用,则有一个类型为int
的对象,它实际上有两个名称:
int x = 0, &y = x;
引用的初始值设定项是x
对象本身,而不是x
的值。
当我们声明一个函数参数作为参考时,它变成一个“参考参数”。函数通过该参数接收值的方式改变了从C继承的通常的“pass by value”语义。
也可以绑定对const
类型的引用。 Const参考参数很好奇;他们可以接收文字对象作为值:
void foo(const int &x); // can be called as foo(42); !
const引用很有用,因为当你将const引用传递给类对象时,它类似于“按值传递”,但是更便宜,因为对象本身已经传递(不会发生复制构造)。
将Const引用引入到C ++中以解决“复制构造函数的参数应该是什么?”的问题。复制构造函数看起来不像这样:
some_class::some_class(some_class original_obj) { /*...*. }
因为这会产生鸡与蛋的问题:将对象传递给复制构造函数需要一个副本(由于按值语义),这需要一个复制构造函数! Const参考发明救援:
some_class::some_class(some_class &original_obj) { /*...*. }
问题解决了;复制构造函数通过引用接收对象,但是以一种准安全的方式,因为该对象是准不可修改的。 (准,因为在某些时候,发明mutable
关键字是为了在const
个对象中打洞。)