Language agnostic 什么';通过引用传递和通过值传递的区别是什么?

Language agnostic 什么';通过引用传递和通过值传递的区别是什么?,language-agnostic,pass-by-reference,pass-by-value,Language Agnostic,Pass By Reference,Pass By Value,两者的区别是什么 通过引用传递的参数 通过值传递的参数 你能给我举一些例子吗?这是一种将参数传递给函数的方法。通过引用传递意味着被调用函数的参数将与调用方传递的参数相同(不是值,而是标识——变量本身)。“按值传递”表示被调用函数的参数将是调用者传递的参数的副本。值将是相同的,但标识(变量)是不同的。因此,在一种情况下,被调用函数对参数的更改会更改传递的参数,而在另一种情况下,只会更改被调用函数中参数的值(这只是一个副本)。匆匆忙忙: Java只支持按值传递。始终复制参数,即使在复制对对象的引用

两者的区别是什么

  • 通过引用传递的参数
  • 通过值传递的参数

  • 你能给我举一些例子吗?

    这是一种将参数传递给函数的方法。通过引用传递意味着被调用函数的参数将与调用方传递的参数相同(不是值,而是标识——变量本身)。“按值传递”表示被调用函数的参数将是调用者传递的参数的副本。值将是相同的,但标识(变量)是不同的。因此,在一种情况下,被调用函数对参数的更改会更改传递的参数,而在另一种情况下,只会更改被调用函数中参数的值(这只是一个副本)。匆匆忙忙:

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

    因为我的语言是C++,我会在这里使用< /P>

    //将指针(在java中称为引用)传递给整数
    按值(int*p)无效调用{/:1
    p=零;
    }
    //传递一个整数
    无效调用值(int p){/:2
    p=42;
    }
    //通过引用传递整数
    按引用无效调用(int&p){/:3
    p=42;
    }
    //这是传递引用的java风格。NULL在那里被称为“NULL”。
    通过特殊值无效调用(int*p){/:4
    *p=10;//更改p指向的内容(java中的“p引用的内容”)
    //仅更改参数的值,但*不*的
    //调用者传递的参数。因此它是按值传递的:
    p=零;
    }
    int main(){
    int值=10;
    int*指针=&value;
    按_值(指针)调用_;/:1
    断言(指针==&value);//指针已复制
    按_值调用_(value);/:2
    断言(值==10);//值已复制
    通过引用调用(值);/:3
    assert(value==42);//值是通过引用传递的
    按值调用特殊(指针);/:4
    //已复制指针,但更改了指针引用的内容。
    断言(value==10&&pointer==&value);
    }
    
    Java中的一个例子不会有什么坏处:

    类示例{
    int值=0;
    //类似于:C++示例中的4例
    静态void accept_引用(示例e){/:1
    e、 value++;//将更改引用的对象
    e=null;//将只更改参数
    }
    //类似于:C++示例中的2种情况
    静态void接受_原语(int v){/:2
    v++;//将只更改参数
    }        
    公共静态void main(字符串…参数){
    int值=0;
    示例ref=新示例();//引用
    //注意,我们传递的是引用,而不是对象。我们不能
    //传递对象。复制引用(按值传递)。
    接受参考(ref);/:1
    assert ref!=null&&ref.value==1;
    //原语int变量被复制
    接受_原语(值);/:2
    断言值==0;
    }
    }
    
    维基百科

    这家伙几乎把它钉死了:


    当通过ref传递时,基本上就是传递一个指向变量的指针。传递值传递变量的副本。在基本用法中,这通常意味着对变量的pass by ref更改将被视为调用方法,而pass by value则不会被看到。

    以下是一个示例:

    #包括
    void by_val(int arg){arg+=2;}
    void by_ref(int&arg){arg+=2;}
    int main()
    {
    int x=0;
    例如:

    类狗
    { 
    公众:
    barkAt(const std::string和pOtherDog);//const引用
    barkAt(std::string pOtherDog);//值
    };
    

    const&
    通常是最好的。您不会招致构造和破坏惩罚。如果引用不是const,则您的接口建议它将更改传入的数据。

    通过值发送存储在指定变量中的数据副本,通过引用发送到变量本身的直接链接。因此,如果y您通过引用传递变量,然后在传入的块内更改变量,原始变量将被更改。如果您仅通过值传递,则传入的块将无法更改原始变量,但您将获得调用时包含的任何内容的副本。

    一个主要区别它们之间是值类型变量存储值,因此在方法调用中指定值类型变量会将该变量的值的副本传递给方法。引用类型变量存储对对象的引用,因此指定引用类型变量作为参数会将引用对象的实际引用的副本传递给方法。即使引用本身是通过值传递的,该方法仍然可以使用它接收到的引用与原始对象交互并可能修改原始对象。类似地,当通过return语句从方法返回信息时,该方法返回存储在值类型变量中的值的副本或存储在引用类型变量。当返回引用时,调用方法可以使用该引用与被引用对象交互。因此,实际上,对象总是通过引用传递

    在c#中,要通过引用传递变量,以便被调用的方法可以修改变量的,c#提供关键字ref和out
    #include <iostream>
    
    using namespace std;
    
    void funct1(int a){ //pass-by-value
        a = 6; //now "a" is 6 only in funct1, but not in main or anywhere else
    }
    void funct2(int &a){ //pass-by-reference
        a = 7; //now "a" is 7 both in funct2, main and everywhere else it'll be used
    }
    
    int main()
    {
        int a = 5;
    
        funct1(a);
        cout<<endl<<"A is currently "<<a<<endl<<endl; //will output 5
        funct2(a);
        cout<<endl<<"A is currently "<<a<<endl<<endl; //will output 7
    
        return 0;
    }
    
    void foo(int param) {  // line 1
      param += 1;
    }
    
    void bar() {
      int arg = 1;  // line 2
      foo(arg);     // line 3
    }
    
    int arg = 1;
    int another_variable = arg;
    
    int arg = 1;
    int another_variable = arg;
    another_variable = 2;
    
    assert arg == 1; // true
    assert another_variable == 2; // true
    
    void foo(int param) {
      param += 1;
    }
    
    void bar() {
      int arg = 1;
      foo(arg);
    }
    
    // entering function "bar" here
    int arg = 1;
    // entering function "foo" here
    int param = arg;
    param += 1;
    // exiting function "foo" here
    // exiting function "bar" here
    
    // entering function "bar" here
    int arg = 1;
    // entering function "foo" here
    // aha! I note that "param" is just another name for "arg"
    arg /* param */ += 1;
    // exiting function "foo" here
    // exiting function "bar" here
    
    void foo(int& param) {
      param += 1;
    }
    
    void bar() {
      int arg = 1;
      foo(arg);
    }
    
       void printvalue(int x) 
       {
           x = x + 1 ;
           cout << x ;  // 6
       }
    
       int x = 5;
       printvalue(x);
       cout << x;    // 5
    
       void printvalue(int &x) 
       {
          x = x + 1 ;
          cout << x ; // 6
       }
    
       int x = 5;
       printvalue(x);
       cout << x;   // 6
    
       void printvalue(int* x) 
       {
          *x = *x + 1 ;
          cout << *x ; // 6
       }
    
       int x = 5;
       printvalue(&x);
       cout << x;   // 6