【问题标题】:Python, Java, C: Pass by Reference or Pass by Value Differences [duplicate]Python,Java,C:按引用传递或按值传递差异[重复]
【发布时间】:2013-09-17 18:17:06
【问题描述】:

我刚刚看了下面这篇关于引用传递和值传递是什么意思的文章:http://qntm.org/call

所以只是为了确保我理解正确......这是否意味着在函数中按值调用不会改变原始输入,只会改变该输入的本地副本?但是,由于在 Java 和 Python 中,值实际上是对值的引用,这是否意味着在函数中按值调用会改变原始输入?

【问题讨论】:

  • 改变局部变量引用不会改变你传入的那个。通过引用访问它来修改对象会改变那个对象。
  • 输入到底是什么意思?
  • 输入作为您传递给函数的变量。抱歉,如果我的词汇量不够大,我正在努力!
  • 投票结束时“过于宽泛”,因为涵盖所有三种语言的任何好的答案都太长了。
  • 感谢 Sotirios 和 Joshua 的详细解释!现在对我来说很有意义!

标签: java python c


【解决方案1】:

这取决于您输入的确切含义,特别是您是否指在调用站点作为参数出现的变量,例如,x in:

Object x = ...;
someMethod( x );

或者您正在谈论被调用函数将看到的实际对象,例如,实际的 Object 实例:

someMethod( new Object() );

变量的(即它们引用的对象)不会改变,但你仍然可以对你得到的对象做一些事情。例如,

void appendX( StringBuilder sb ) {
  sb.append('x');
}

void foo() {
  StringBuilder builder = ...
  appendX( builder );
  builder.toString(); // will contain 'x' because you worked with the object that 
                      // is the value of the variable `builder`.  When appendX was
                      // was invoked, the value of its variable `sb` was the same 
                      // object that is the value of foo's `builder`.  Without 
                      // changing what value the variable `builder` refers to, we
                      // did "change" the object (i.e., we appended 'x').
}

但是,更新方法中的引用不会更改方法之外的任何引用。在方法内部,您不能通过分配给方法的一个参数来更改方法外部的变量所引用的对象。例如:

void setNull( StringBuilder sb ) {
  sb = null;
}

void foo() {
  StringBuilder builder = ...
  appendX( builder );
  builder == null;  // false, because the value of the variable `builder` is still the 
                    // same object that it was before.  Setting variable `sb` in setNull
                    // to null doesn't affect the variable `builder`. The variables are
                    // just a name so that you can refer to an value.  The only way to
                    // what value a variable refers to is with an assignment.
}

【讨论】:

  • 我认为这是解释这种细微差别的最佳方式。 +1。
  • @publ1c_stat1c 这是一个有趣的细微差别,因为如果您使用的语言(例如 Java)无法通过调用带有变量的方法来修改变量的值作为源中的一个参数(例如,someMethod( x )),那么很难想象为什么任何语言都会你这样做。然而,在某些语言中,您可以。 :)
【解决方案2】:

在 Java 中,有几种基本类型的变量:int、long、float、double 和引用。 引用是您通常所说的对象,例如字符串。但是,引用变量中实际存储的不是对象本身,而是实际对象在内存中的地址。

在 Java 中你永远不会看到这个,如果你写 String str = "hello",你会认为 str 是字符串“hello”。但实际上,str 包含一个数字 - 一个内存地址 - 存储实际字符串“hello”的位置。

在 Java 中调用方法时,会复制其参数(按值传递)。即使对于像字符串这样的对象也是如此——除了实际对象没有被复制,只是引用。但是,由于引用指向未复制的某些内容(内存中的实际对象位置),您可以使用引用来修改实际对象,即使在函数之外。

在 C 中,您实际上可以使用指针通过引用传递:

void changeA(int* a) {
    *a = 5
} 
int main(void) {
    a = 10;
    changeA(&a); // pass by reference - &a means "address of a", similar to a reference in java
    printf("a: %d\n", a); // prints "5"
}

【讨论】:

    猜你喜欢
    • 2012-03-12
    • 2013-09-15
    • 2019-05-07
    • 2013-12-02
    • 2023-03-07
    • 1970-01-01
    • 2012-03-13
    • 2014-09-10
    • 2021-11-04
    相关资源
    最近更新 更多