术语“引用”的起源,如“通过引用”

Posted

技术标签:

【中文标题】术语“引用”的起源,如“通过引用”【英文标题】:Origin of term "reference" as in "pass-by-reference" 【发布时间】:2010-12-23 19:44:36 【问题描述】:

Java/C# 语言律师喜欢说他们的语言通过值传递引用。这意味着“引用”是在调用函数时复制的对象指针。

同时,在 C++ 中(在 Perl 和 php 中也是更动态的形式),引用是其他名称(或动态情况下的运行时值)的别名。

我对这里的词源感兴趣。 “参考”一词的早期用途是什么?让我们看看 pre-Java,但如果你知道 pre-C++ 的用途,那我也会感兴趣。

(我知道词汇会发生变化等,但我只是对历史感兴趣)。

【问题讨论】:

【参考方案1】:

我想您可以将其追溯到 C,它拥有(并且仍然拥有)pointers 以及引用和取消引用运算符。

【讨论】:

我从未听说过与 C 相关的“参考”一词。 "The C Reference Manual" (* ahem * ;) ) from 1975 (see cm.bell-labs.com/cm/cs/who/dmr/cman.pdf ) 在几个地方使用了“reference”:任何上下文中的数组(特别是作为实际参数)都被认为是指向数组第一个元素的指针”,“对相同外部标识符的引用是对同一对象的引用”,并且至少在其他地方。我手边没有可搜索的 K&R 或 ANSI C 副本。 很公平,尽管我似乎无法收回我的反对票。对不起:(【参考方案2】:

认为它可以追溯到 PASCAL,可能更远。

原来的 FORTRAN 通过引用传递参数:传递变量、数组或矩阵的地址。

ALGOL-60 按名称或按值传递。点名被证明是一个巨大的错误,它教会了编程语言设计者很多关于不该做的事情。 PASCAL 通过值或引用传递参数,取决于参数是否标记为 VAR(按引用传递)或不(按值传递)。

【讨论】:

很好的答案!所以我猜 Fortran 出现在 57 年代,而 Pascal 出现在 70 年代初?他们是使用“参考”一词还是仅使用概念。 @Paul - 他们使用了不同的术语;看我的回答 请注意,Pascal 修订报告 (fh-jena.de/~kleine/history/languages/…) 没有提及“通过引用”,而是使用“变量引用”。 (第 9.1.2 节)【参考方案3】:

(此回复仅涉及 C#,AFAIK)

不要告诉 Eric Lippert 引用是指针 ;-p 它们发生在 MS C# / .NET 中是一样的,但这是一个实现细节。引用是一个不透明的、安全的“东西”,它允许你定位一个对象。指针是内存地址。他们努力确保您始终知道您的意思...

实现一个将两者视为相同的 CLI 和编译器是完全可行的;不过,您仍然会向该值传递 reference

References are not addresses

【讨论】:

有趣。我相信 Java 参考手册在某些时候称它们为指针 - 我更熟悉 Java 案例。 来自 Eric Lippert 的精彩链接! 指针不是内存地址。指针通常是内存地址,但它不是内存地址。例如,有些系统具有分段内存,其中指针可能是偏移量(“近”指针)或选择器加上偏移量(“远”指针)。根据定义,C# 指针具有与指针相同的操作语义。指针是可以反弹的引用,而这正是 C# 所拥有的。 @DrPizza - 嗯......去展示我所知道的。很公平;我将保留“原样”作为与引用与内存地址相关的注释,但您的观点已被记录。我必须深入挖掘定义才能尝试挑战它,所以我会假设它是正确的。【参考方案4】:

“引用”一词的最早用法(如“通过引用”)可能在暗淡的古代中丢失了。当然,FORTRAN 通过引用传递它的参数并且总是这样做的。

提到“点名呼唤”让我想起了 Nickolas Wirth(帕斯卡的发明者)的一个笑话(可能是唯一一个):

“教授,你的姓怎么读?”

"如果按名字调用就是V-I-R-T,如果按值调用就是W-O-R-T-H"

而且人们说程序员没有幽默感!

【讨论】:

【参考方案5】:

Richard E Fairley 于 1973 年 3 月在论文 "Semantic Models of Parameter Passing" 中使用了术语“引用调用”。

在早期,术语不一致。例如,Fortran 66 specification 使用短语“association by name”和“association by value”。我们现在将这些称为“引用调用”和“值调用”。相比之下,Algol 60 specification (1962) 使用了“按名称调用”和“按值调用”这两个术语……而这两者都不是我们目前所说的按引用调用。

编辑:对于那些希望将指定 Fortran 66 的先驱者标记为对使用“名称关联”这一短语感到困惑的人,请考虑以下几点:

    Fortran 66 是第一次尝试通过引用(我们现在称之为)调用来指定一种语言。

    这只是第二次尝试使用支持参数传递的子例程指定语言。

    Fortran 66 的“名称关联”可以被视为 Algol 60 的“名称调用”的受限(退化)形式。限制是在 Fortran 中,名称必须是简单的变量或数组名称,而在 Algol 60 中,它可以是任何表达式。

    当时(1966 年)并不清楚 Algol 60 的“点名呼唤”注定要作为一个坏主意而被放弃。事实上,当我在 1977 年作为一名本科生学习 Algol 60 时,我不记得讲师提出“点名呼叫”是一个坏主意。 (它被呈现为难以理解......但这是另一回事。)

【讨论】:

“association by name”是引用(听起来像别名),还是 Algol 风格的按值调用(有各种奇怪,在另一个答案中描述)? @Paul - 正如我所说,这就是我们现在所说的“引用调用”。检查链接的规范。 功能语言仍然使用术语“按名称调用”和“按值调用”,以及附加分类:“按需要调用”(例如 Haskell)。跨度> 好发现!但我不会说“不一致”,这有一种困惑的暗示。似乎不同的人始终选择不同的命名法,但知道他们指的是相同的术语,并且“引用调用”(或“引用传递”)胜过“关联”。 不一致!= 困惑。我只是说没有达成共识。【参考方案6】:

我一直认为这个想法是为了区分指针和引用。引用将指向该对象,无论它在哪里。

指针指向内存中的地址,但在托管语言中,这可能会改变。因此,您必须通过引用进行抽象,以确保您的代码始终有效。例如。在托管语言中使用数组时,您不能只编写reference++,因为垃圾收集器可以移动您的数组。请注意,我很清楚 c# 中的固定和不安全代码:)。

正如我的 java 导师也向我解释过的那样,另一个带有参考的关键“概念”是你不能操纵它。指针供程序员管理,引用供编译器/运行时管理。

【讨论】:

【参考方案7】:

我认为您应该在历史搜索中使用的术语是“call-by-reference”而不是“pass-by-reference”。例如,***将“Pass-by-reference”重定向到“Evaluation Strategy”,其中列出了call-by-reference。

在 Google 图书中使用“call-by-reference”作为搜索词可以找到来自 “The Main Features of CPL”来自 The Computer Journal,1963 年 8 月; 6: 134 - 143(英国计算机协会)

三种参数调用方式是可能的; value调用(相当于ALGOL按值调用),substitution调用(相当于ALGOL按名称调用),reference调用强>。后一种情况下,交出实际参数的LH值;这对应于 Strachey 和 Wilkes (1961) 建议的“简单名称调用”。注意与三种初始化的对应关系...

后一种“按名称调用”可能与 Algol 60 规范中使用的术语相同,Stephen C 早些时候在此线程中指出。

(我认为“Strachey and Wilkes”来自 CACM 1961,但我无权访问任何源文本进行验证。)

【讨论】:

嗯,您为“Strachey & Wilkes”链接的 ACM 门户引文页面它来自 CACM 第 4 卷第 11 期(1961 年 11 月)。【参考方案8】:

“参考”一词的使用前后不一致。

在某些情况下,它是有形实体,例如 Simula/Delphi/Java/C# 对象引用。您可以比较它们(与 null 和彼此)并将它们作为参数(按值或按引用)传递。 大多数语言都支持以完全不透明的方式将引用作为参数传递的一种模式。 C++ 是唯一一种扩展这种不透明模型并让您拥有引用字段和变量的语言(我知道)(int& r = i;)。

一方面,这意味着 C++ 引用与 C# 引用非常不同。

我认为我们在这里遗漏了一些行话来区分这两种不同形式的“参考”。

另见SO: History of public/private/protected。

【讨论】:

嗯,我的脑海里浮现 Simula 是 60 年代后期(67?)所以它似乎是“引用”的第一个“新用途”来表示托管对象。看起来是否准确(我不知道它是如何“管理”的)? 保罗,请参阅链接。 Simula (1967) 引领了通往“参考类型”的道路。但在类型安全的意义上还没有“管理”。【参考方案9】:

请注意,在 60 年代(是的,到 70 年代),“参考”意味着使用某物的名称。这与较早的哲学和语言术语“参照”和“参照”的用法一致。来自Fortran 77:

2.12参考

变量、数组元素或子字符串引用是变量、数组的外观 元素或子字符串名称,分别在需要该值的上下文中的语句中 在执行可执行程序期间要使用的实体。当一个 对实体的引用被执行,它的当前值是可用的。在本标准中,行为 定义实体不被视为对该实体的引用。

过程引用是上下文中语句中过程名称的外观 要求在执行过程中执行过程指定的动作 可执行程序。执行过程引用时,该过程必须是 可用。

【讨论】:

这似乎是在“取消引用”的意义上说,而不是“引用调用”。引用一词还有其他用途吗? 在引用被称为引用之前,当“引用调用”被称为“名称关联”时(正如斯蒂芬 C 指出的那样),“引用”有不同的用途。从 60 年代到现在,“参考”的含义发生了变化。 上述和斯蒂芬的回答(尤其是第 3 点)提出了一种可能的词源:“association by name”是“按名称调用”的更严格版本,只允许变量引用(在“命名某些东西的东西”)与虚拟参数相关联。这是否有任何道理取决于这两种调用语义之间的区别在当时有多明显,以及是否有人愿意让两者更加不同。

以上是关于术语“引用”的起源,如“通过引用”的主要内容,如果未能解决你的问题,请参考以下文章

C++ 如何处理 const 标记的通过引用传递的类,这些类不是直接更改而是从另一端更改的? [复制]

通过引用javascript传递原始变量[重复]

1.labview如何通过引用调用子程序;

Java 是“按引用传递”还是“按值传递”?

Java 是“按引用传递”还是“按值传递”?

Java 是“按引用传递”还是“按值传递”?