gpt4 book ai didi

language-agnostic - 按引用传递与按值传递有什么区别?

转载 作者:行者123 更新时间:2023-12-03 03:54:22 25 4
gpt4 key购买 nike

之间有什么区别

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

  • 请给我一些例子好吗?

    最佳答案

    首先, CS 理论中定义的“按值传递与按引用传递”的区别现在已过时 因为 最初定义为“通过引用传递”的技术已经失宠现在很少使用。1
    较新的语言 2 倾向于使用不同(但相似)的技术来实现相同的效果 (见下文)这是混淆的主要来源。
    造成混淆的第二个来源是 在“通过引用传递”中,“引用”的含义比一般术语“引用”更窄 (因为该短语早于它)。

    现在,真正的定义是:

  • 当参数为 通过引用 ,主叫方和被叫方使用相同的变量 为参数。如果被调用者修改了参数变量,效果对调用者的变量是可见的。
  • 当参数为 按值传递 ,主叫方和被叫方有两个自变量 具有相同的值。如果被调用者修改了参数变量,调用者是看不到效果的。

  • 在这个定义中需要注意的是:
  • 这里的“变量”是指调用者的(本地或全局)变量本身 - 即如果我通过引用传递局部变量并分配给它,我将更改调用者的变量本身,而不是例如无论它指向什么,如果它是一个指针。
  • 这现在被认为是不好的做法(作为隐式依赖)。因此,几乎所有较新的语言都是完全或几乎完全是按值传递的。 在函数不能返回多个值的语言中,引用传递现在主要以“输出/输入参数”的形式使用。

  • “通过引用传递”中“引用”的含义 .与一般“引用”术语的区别在于这个“引用”是临时的和隐含的。 被叫基本上得到的是与原始变量在某种程度上“相同”的“变量”。 这种效果的具体实现方式是无关紧要的(例如,该语言还可能公开一些实现细节——地址、指针、取消引用——这些都是无关紧要的;如果净效果是这样,则它是通过引用传递的)。

  • 现在,在现代语言中,变量往往是“引用类型” (另一个概念在“通过引用传递”之后发明并受到它的启发),即实际对象数据单独存储在某处(通常在堆上),并且只有对它的“引用”才会保存在变量中并作为参数传递.3
    传递这样的引用属于按值传递因为变量的值在技术上是引用本身,而不是被引用的对象。然而, 对程序的净影响可以与传值或传引用相同:
  • 如果引用只是从调用者的变量中获取并作为参数传递,则这与传递引用具有相同的效果:如果引用的对象在被调用者中发生了变异,则调用者将看到更改。
  • 但是,如果重新分配持有此引用的变量,它将停止指向该对象,因此对该变量的任何进一步操作都会影响它现在指向的任何内容。

  • 为了获得与传值相同的效果,在某个时间点制作对象的副本。选项包括:
  • 调用者可以在调用之前制作一个私有(private)副本,然后给被调用者一个引用。
  • 在某些语言中,某些对象类型是“不可变的”:对它们进行的任何似乎改变值的操作实际上都会创建一个全新的对象,而不会影响原始对象。因此,将这种类型的对象作为参数传递始终具有按值传递的效果:如果需要更改,将自动为被调用者创建副本,并且调用者的对象永远不会受到影响。
  • 在函数式语言中,所有对象都是不可变的。



  • 如您所见, 这对技术与定义中的技术几乎相同,只是有一个间接级别:只需将“变量”替换为“引用对象”即可。
    它们没有商定的名称,这会导致扭曲的解释,例如“按值调用,其中值是引用”。 1975 年,Barbara Liskov 提出了“ call-by-object-sharing”(或有时只是“共享调用”)这个词,尽管它从未流行起来。此外,这些短语都没有与原始对平行。难怪在没有更好的东西的情况下,旧术语最终被重用,导致混淆。 4

    注意 : 很长一段时间,这个答案曾经说:

    Say I want to share a web page with you. If I tell you the URL, I'mpassing by reference. You can use that URL to see the same web page Ican see. If that page is changed, we both see the changes. If youdelete the URL, all you're doing is destroying your reference to thatpage - you're not deleting the actual page itself.

    If I print out the page and give you the printout, I'm passing byvalue. Your page is a disconnected copy of the original. You won't seeany subsequent changes, and any changes that you make (e.g. scribblingon your printout) will not show up on the original page. If youdestroy the printout, you have actually destroyed your copy of theobject - but the original web page remains intact.


    除了“引用”的狭义含义之外,这大部分是正确的——它既是临时的又是隐式的(它不是必须的,但显式和/或持久性是附加功能,而不是传递引用语义的一部分,如上所述)。更接近的类比是给你一份文件的副本与邀请你处理原件。

    1除非您使用 Fortran 或 Visual Basic 进行编程,否则这不是默认行为,并且在现代使用的大多数语言中,甚至不可能实现真正的按引用调用。
    2相当多的老年人也支持它
    3在几种现代语言中,所有类型都是引用类型。这种方法由语言 CLU 于 1975 年首创,此后被许多其他语言采用,包括 Python 和 Ruby。还有更多的语言使用混合方法,其中一些类型是“值类型”,另一些是“引用类型”——其中包括 C#、Java 和 JavaScript。
    4 循环使用一个合适的旧术语本身并没有什么坏处,但人们必须以某种方式明确每次使用的含义。不这样做正是不断引起困惑的原因。

    关于language-agnostic - 按引用传递与按值传递有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/373419/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com