传递引用与价值传递之间有什么区别?

有什么区别

  • 通过引用传递的参数
  • 通过值传递的参数?
  • 请给我一些例子吗?


    通过引用传递参数时,调用者和被调用者对参数使用相同的变量 。 如果被调用者修改参数变量,则该效果对调用者的变量可见。

    按值传递参数时,调用者和被调用者有两个具有相同值的独立变量 。 如果被调用者修改参数变量,则调用者不可见该效果。

    但是 ,如果所讨论的值是可变引用类型对象或者间接引用了其他值,那么您可以在值调用环境中模拟引用引用:如果被调用者修改对象(或其他指向的值对象),这些修改对调用者是可见的。 但是仿真不完全相同,因为只有对对象而不是变量的修改是可见的。 这会导致扭曲的解释,例如“以值为参照的价值调用”。 这种令人困惑的事态是当今有多少流行的编程语言,因此人们经常会将价值传递的可变对象与引用引用混淆。

    有关更多解释,请参阅下面的其他答案。


    :很长一段时间,这个答案用于说:

    假设我想与你分享一个网页。 如果我告诉你网址,我会通过参考。 您可以使用该URL来查看我可以看到的相同网页。 如果该页面发生更改,我们都会看到更改。 如果你删除了URL,你所做的只是摧毁你对该页面的引用 - 你并没有删除实际的页面本身。

    如果我打印出这个页面并给你打印输出,我就会传递价值。 您的页面是原件的断开连接副本。 您不会看到任何后续更改,并且您所做的任何更改(例如在您的打印输出上涂鸦)都不会显示在原始页面上。 如果你摧毁了打印输出,你实际上已经销毁了你的对象副本 - 但原始网页保持不变。

    这是一个简单的比喻,很容易理解,它得到了这篇文章数百个upvotes。 但是,这个比喻是有缺陷的:引用引用和值引用不像URL。 (像C#这样的语言中的引用类型就像一个URL;请参阅Jon Skeet关于.NET中引用类型的详细介绍,但引用类型与引用不同。)

    由于这个比喻实际上并不正确,因此已将其从此答案中删除。 另请参阅下面的讨论内容。


    这是如何将参数传递给函数的一种方式。 通过引用传递意味着被调用函数的参数将与调用者传递的参数(不是值,而是标识 - 变量本身)相同。 按值传递意味着被调用函数的参数将成为调用者传递参数的副本。 价值将是相同的,但身份 - 变量 - 是不同的。 因此,在一种情况下,由被调用函数完成的参数更改会改变传递的参数,而在另一种情况下,会更改被调用函数中的参数值(仅为副本)。 匆忙:

  • Java只支持按值传递。 始终复制参数,即使在复制对象的引用时,被调用函数中的参数也会指向同一对象,并且将在调用者中看到对该对象的更改。 由于这可能会让人困惑,以下是Jon Skeet对此所说的话。
  • C#支持按值传递和按引用传递(关键字ref用于调用者和被调用的函数)。 Jon Skeet在这里也有很好的解释。
  • C ++支持按值传递和按引用传递(在调用函数中使用的引用参数类型)。 你会在下面找到这个解释。
  • 代码

    由于我的语言是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?