传递引用与价值传递之间有什么区别?
有什么区别
请给我一些例子吗?
当通过引用传递参数时,调用者和被调用者对参数使用相同的变量 。 如果被调用者修改参数变量,则该效果对调用者的变量可见。
当按值传递参数时,调用者和被调用者有两个具有相同值的独立变量 。 如果被调用者修改参数变量,则调用者不可见该效果。
但是 ,如果所讨论的值是可变引用类型对象或者间接引用了其他值,那么您可以在值调用环境中模拟引用引用:如果被调用者修改对象(或其他指向的值对象),这些修改对调用者是可见的。 但是仿真不完全相同,因为只有对对象而不是变量的修改是可见的。 这会导致扭曲的解释,例如“以值为参照的价值调用”。 这种令人困惑的事态是当今有多少流行的编程语言,因此人们经常会将价值传递的可变对象与引用引用混淆。
有关更多解释,请参阅下面的其他答案。
注 :很长一段时间,这个答案用于说:
假设我想与你分享一个网页。 如果我告诉你网址,我会通过参考。 您可以使用该URL来查看我可以看到的相同网页。 如果该页面发生更改,我们都会看到更改。 如果你删除了URL,你所做的只是摧毁你对该页面的引用 - 你并没有删除实际的页面本身。
如果我打印出这个页面并给你打印输出,我就会传递价值。 您的页面是原件的断开连接副本。 您不会看到任何后续更改,并且您所做的任何更改(例如在您的打印输出上涂鸦)都不会显示在原始页面上。 如果你摧毁了打印输出,你实际上已经销毁了你的对象副本 - 但原始网页保持不变。
这是一个简单的比喻,很容易理解,它得到了这篇文章数百个upvotes。 但是,这个比喻是有缺陷的:引用引用和值引用不像URL。 (像C#这样的语言中的引用类型就像一个URL;请参阅Jon Skeet关于.NET中引用类型的详细介绍,但引用类型与引用不同。)
由于这个比喻实际上并不正确,因此已将其从此答案中删除。 另请参阅下面的讨论内容。
这是如何将参数传递给函数的一种方式。 通过引用传递意味着被调用函数的参数将与调用者传递的参数(不是值,而是标识 - 变量本身)相同。 按值传递意味着被调用函数的参数将成为调用者传递参数的副本。 价值将是相同的,但身份 - 变量 - 是不同的。 因此,在一种情况下,由被调用函数完成的参数更改会改变传递的参数,而在另一种情况下,会更改被调用函数中的参数值(仅为副本)。 匆忙:
ref
用于调用者和被调用的函数)。 Jon Skeet在这里也有很好的解释。 代码
由于我的语言是C ++,我会在这里使用它
// passes a pointer (called reference in java) to an integer
void call_by_value(int *p) { // :1
p = NULL;
}
// passes an integer
void call_by_value(int p) { // :2
p = 42;
}
// passes an integer by reference
void call_by_reference(int & p) { // :3
p = 42;
}
// this is the java style of passing references. NULL is called "null" there.
void call_by_value_special(int *p) { // :4
*p = 10; // changes what p points to ("what p references" in java)
// only changes the value of the parameter, but *not* of
// the argument passed by the caller. thus it's pass-by-value:
p = NULL;
}
int main() {
int value = 10;
int * pointer = &value;
call_by_value(pointer); // :1
assert(pointer == &value); // pointer was copied
call_by_value(value); // :2
assert(value == 10); // value was copied
call_by_reference(value); // :3
assert(value == 42); // value was passed by reference
call_by_value_special(pointer); // :4
// pointer was copied but what pointer references was changed.
assert(value == 10 && pointer == &value);
}
Java中的一个例子不会伤害到:
class Example {
int value = 0;
// similar to :4 case in the c++ example
static void accept_reference(Example e) { // :1
e.value++; // will change the referenced object
e = null; // will only change the parameter
}
// similar to the :2 case in the c++ example
static void accept_primitive(int v) { // :2
v++; // will only change the parameter
}
public static void main(String... args) {
int value = 0;
Example ref = new Example(); // reference
// note what we pass is the reference, not the object. we can't
// pass objects. The reference is copied (pass-by-value).
accept_reference(ref); // :1
assert ref != null && ref.value == 1;
// the primitive int variable is copied
accept_primitive(value); // :2
assert value == 0;
}
}
维基百科
http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_value
http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference
这家伙几乎钉了它:
http://javadude.com/articles/passbyvalue.htm
这里是一个例子:
#include <iostream>
void by_val(int arg) { arg += 2; }
void by_ref(int&arg) { arg += 2; }
int main()
{
int x = 0;
by_val(x); std::cout << x << std::endl; // prints 0
by_ref(x); std::cout << x << std::endl; // prints 2
int y = 0;
by_ref(y); std::cout << y << std::endl; // prints 2
by_val(y); std::cout << y << std::endl; // prints 2
}
链接地址: http://www.djcxy.com/p/455.html
上一篇: What's the difference between passing by reference vs. passing by value?
下一篇: Why is executing Java code in comments with certain Unicode characters allowed?