究竟是什么“通过引用传递”意思? [英] What exactly does "pass by reference" mean?

查看:193
本文介绍了究竟是什么“通过引用传递”意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁有权决定?

编辑:显然我没有成功地完善我的问题。

询问Java的参数传递是如何工作的。我知道看起来像持有对象的变量实际上是一个包含对象引用的变量,并且该引用是按值传递的。
这里有很多关于该机制的精细解释(在链接的线程和其他内容中)和其他地方。

Apparently I haven't succeeded in formulating my question well.
I am not asking how Java's argument passing works. I know that what looks like a variable holding an object is actually a variable holding a reference to the object, and that reference is passed by value. There are lots of fine explanations of that mechanism here (in the linked threads and others) and elsewhere.

问题是关于技术含义术语传递参考。 (结束编辑)

The question is about the technical meaning of the term pass-by-reference. (End edit)

我不确定这是否是SO的正确问题,如果没有道歉,但我不知道更好的地方。在这里的其他问题中已经说了很多,例如 Java是通过参考传递。或按值传递?通过引用传递或通过价值?,但我没有找到该术语含义的权威答案。

I am not sure if this is the right kind of question for SO, apologies if not, but I don't know a better place. Much has already been said in other questions here, for example Is Java "pass-by-reference" or "pass-by-value"? and pass by reference or pass by value?, but I haven't found an authoritative answer to the question what the term means.

我认为通过参考传递表示将引用(通常是指针)传递给对象,因此被调用者可以修改调用者看到的对象,而按值传递意味着复制对象,并让被调用者对副本有乐趣(明显的问题) :如果对象包含引用,深层复制或浅层,那该怎么办。

唱出FW出现 lot 地方 通过引用传递就是这样,这里有一些论点,它意味着更多,但定义仍然是读取

I have thought that "pass by reference" means "pass a reference (usually a pointer) to the object", so the callee can modify the object the caller sees, while "pass by value" means copying the object, and letting the callee have fun with the copy (obvious problem: what if the object contains references, deep copy or shallow).
Sing the FW turns up lots of places saying "pass by reference" means just that, here there's some argument that it means more, but the definition still reads


一个ParameterPassing模式将实际参数的引用(或者如果你想在政治上不正确,指针)传递给形式参数;当被调用者需要形式参数时,它会取消引用指针来获取它。

A ParameterPassing mode where a reference (or if you want to be politically incorrect, a pointer) to the actual parameter is passed into the formal parameter; when the callee needs the formal parameter it dereferences the pointer to get it.

我没有找到很多地方给出更强的定义这个术语,在这个页面上,我找到了形式参数的左值设置为实际参数的左值。并且,如果我理解正确,则使用相同的定义此处(正式参数仅仅是行为作为实际参数的别名。)

I haven't found many places giving a stronger definition for the term, on this page, I found "The lvalue of the formal parameter is set to the lvalue of the actual parameter." and, if I understand correctly, the same definition is used here ("The formal parameter merely acts as an alias for the actual parameter.")

事实上,我发现使用更强定义的唯一地方是反对Java中的对象的观点通过引用传递(这可能是由于我缺乏google-fu)。

In fact, the only places I found where the stronger definition is used are places arguing against the notion that in Java, objects are passed by reference (that may be due to my lacking google-fu).

所以,如果我把事情做好,请参考传递

So, if I got things straight, pass-by-reference

class Thing { ... }
void byReference(Thing object){ ... }
Thing something;
byReference(something);

根据第一个定义大致对应于(在C中)

according to the first definition would roughly correspond to (in C)

struct RawThing { ... };
typedef RawThing *Thing;
void byReference(Thing object){
    // do something
}
// ...
struct RawThing whatever = blah();
Thing something = &whatever;
byReference(something); // pass whatever by reference
// we can change the value of what something (the reference to whatever) points to, but not
// where something points to

从这个意义上说,Java通过引用传递对象就足够了。但根据第二个定义,传递引用意味着或多或少

and in that sense, saying that Java passes objects by reference would be adequate. But according to the second definition, pass-by-reference means more or less

struct RawThing { ... };
typedef RawThing *RawThingPtr;
typedef RawThingPtr *Thing;
void byReference(Thing object){
    // do something
}
// ...
RawThing whatever = blah();
RawThingPtr thing_pointer = &whatever;
byReference(&thing_pointer); // pass whatever by reference
// now we can not only change the pointed-to (referred) value,
// but also where thing_pointer points to

由于Java只允许你指向对象(限制你可以用它们做什么)但是没有指针指针,从这个意义上说,Java通过引用传递对象是完全错误的。

And since Java only lets you have pointers-to-objects (limiting what you can do with them) but doesn't have pointers-to-pointers, in that sense, saying that Java passes objects by reference is totally wrong.

所以,


  1. 我是否已充分理解上述传递参考的定义?

  2. 是否还有其他定义?

  3. 是否有共识定义是正确的,如果是这样,哪个?


推荐答案

当然,不同的人目前对传递参考的含义有不同的定义。这就是为什么他们不同意某些东西是否通过引用传递。

Sure, different people currently have different definitions of what "pass-by-reference" means. And that is why they disagree on whether something is pass-by-reference or not.

但是,无论你使用什么定义,都必须始终使用它 跨语言。你不能说一种语言具有传值,并且在另一种语言中具有完全相同的语义,并且说它是通过引用传递的。指出语言之间的类比是解决这一争议的最佳方式,因为虽然人们可能对特定语言中的传递模式有强烈的意见,但当你将相同的语义与其他语言进行对比时,它有时会带来反直觉的结果,迫使他们重新考虑他们的定义。

However, whatever definition you use, you must use it consistently across languages. You can't say that one language has pass-by-value, and have the exact same semantics in another language and say that it is pass-by-reference. Pointing out the analogies between languages is the best way to address this dispute, because although people might have strong opinions about the passing modes in particular languages, when you contrast the identical semantics with other languages, it sometimes brings counter-intuitive results that force them to re-think their definition.


  • 一个主要观点是Java只是按值传递。 (在Internet上随处搜索,您将找到这种观点。)此视图是对象不是值,但始终通过引用进行操作,因此它是按值分配或传递的引用。这个视图认为传递引用的测试是否可以分配给调用范围中的变量。

如果一个人同意这个观点,那么还必须考虑大多数语言,包括 Python,Ruby,OCaml,Scheme,Smalltalk,SML,Go,JavaScript,Objective-C 等多种语言。 仅按值传递。如果其中任何一个让你觉得奇怪或违反直觉,我挑战你指出为什么你认为在Java中的对象中任何一种语言中的对象的语义不同。 (我知道其中一些语言可能明确声称它们是传递引用;但它与它们所说的无关;必须根据实际行为对所有语言应用一致的定义。)

If one agrees with this viewpoint, then one must also consider most languages, including as diverse ones as Python, Ruby, OCaml, Scheme, Smalltalk, SML, Go, JavaScript, Objective-C, etc. as pass-by-value only. If any of this strikes you as strange or counterintuitive, I challenge you to point out why you think it is different between the semantics of objects in any of those languages from objects in Java. (I know that the some of these languages may explicitly claim that they are pass-by-reference; but it is irrelevant what they say; a consistent definition must be applied to all languages based on the actual behavior.)


  • 如果您采用相反的观点认为Java中的对象是传递引用,那么您还必须将C视为传递引用。

以Java为例:

class Thing { int x; }
void func(Thing object){ object.x = 42; object = null; }
Thing something = null;
something = new Thing();
func(something);

在C中,它相当于:

typedef struct { int x; } Thing;
void func(Thing *object){ object->x = 42; object = NULL; }
Thing *something = NULL;
something = malloc(sizeof Thing);
memset(something, 0, sizeof(something));
func(something);
// later:
free(something);

我声称上述语义相同;只有语法不同。唯一的语法差异是:

I claim that the above are semantically equivalent; only the syntax is different. The only syntax differences are:


  1. C需要显式的 * 来表示指针类型; Java的引用(指向对象的指针)类型不需要显式 *

  2. C使用 - > ; 通过指针访问字段; Java只使用

  3. Java使用 new 为a动态分配内存堆上的新对象; C使用 malloc 来分配它,然后我们需要初始化内存。

  4. Java有垃圾收集

  1. C requires an explicit * to denote a pointer type; Java's reference (pointers to objects) types don't need an explicit *.
  2. C uses -> to access a field through a pointer; Java just uses .
  3. Java uses new to dynamically allocate memory for a new object on the heap; C uses malloc to allocate it, and then we need to initialize the memory.
  4. Java has garbage collection

请注意,重要的是,


  1. 调用函数的语法在两种情况下,对象都是相同的: func(something),无需做任何地址或任何事情。

  2. 在这两种情况下,对象都是动态分配的(它可能超出了函数的范围)。

  3. 在这两种情况下,函数内的 object = null; 都不会影响调用范围。

  1. The syntax for calling the function with the object are the same in both cases: func(something), without needing to do anything like taking address or anything.
  2. In both cases, the object is dynamically-allocated (it may live beyond the scope of the function). And
  3. In both cases, the object = null; inside the function does not affect the calling scope.

因此在两种情况下语义都是相同的,所以如果你调用Java pass-by-reference,你也必须调用C pass-by-reference。

So the semantics are the same in both cases, so if you call Java pass-by-reference you must call C pass-by-reference too.

这篇关于究竟是什么“通过引用传递”意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆