版权归原作者所有,如有侵权,请联系我们

[科普中国]-按引用传递

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

通过引用调用(也称为引用传递)是一种评估策略,其中函数接收对用作参数的变量的隐式引用,而不是其值的副本。这通常意味着该函数可以修改(即分配给)用作参数的变量 - 其调用者将看到的内容。因此,可以使用引用呼叫在被叫功能和呼叫功能之间提供附加的通信信道。调用引用语言使程序员更难以跟踪函数调用的效果,并可能引入细微的错误。

介绍许多语言以某种形式支持通过引用调用,但相对较少的语言将其用作默认值。 FORTRAN II是参考调用语言的早期示例。一些语言,如C ++,PHP,Visual Basic .NET,C#和REALbasic,默认按值调用,但为调用引用参数提供特殊语法。 C ++还提供了对const的引用调用。 Rust还提供了引用调用,但默认为不可变(const)引用。可变引用具有与不可变引用类似的语法1。

通过引用调用可以使用按值调用的语言进行模拟,并且不完全支持通过引用调用,通过使用引用(引用其他对象的对象),例如指针(表示其他对象的内存地址的对象) 。 C和ML等语言使用这种技术。它不是一个单独的评估策略-语言按值调用-但有时它被称为按地址调用(也称为按地址传递)。在ML中,参考文献是类型和内存安全的。

通过共享调用(传递一个可以随后变异的对象)来实现类似的效果,在Java,Python和Ruby等语言中使用。

在纯函数式语言中,两种策略之间通常没有语义差异(因为它们的数据结构是不可变的,因此函数不可能修改其任何参数),因此它们通常被描述为按值调用,即使实现经常在内部使用引用来提高效率。

例子以下示例演示了E中的引用调用:

def modify(var p, &q) { p := 27 # passed by value: only the local parameter is modified q := 27 # passed by reference: variable used in call is modified}? var a := 1# value: 1? var b := 2# value: 2? modify(a, &b)? a# value: 1? b# value: 27以下是一个按地址调用的示例,它模拟C中的引用调用:

void modify(int p, int* q, int* r) { p = 27; // passed by value: only the local parameter is modified *q = 27; // passed by value or reference, check call site to determine which *r = 27; // passed by value or reference, check call site to determine which}int main() { int a = 1; int b = 1; int x = 1; int* c = &x; modify(a, &b, c); // a is passed by value, b is passed by reference by creating a pointer (call by value), // c is a pointer passed by value // b and x are changed return 0;}按引用传递的重要特点传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

示例如下:

public class TempTest { private void test1(A a){ a.age = 20; System.out.println("test1方法中的age="+a.age); } public static void main(String[] args) { TempTest t = new TempTest(); A a = new A(); a.age = 10; t.test1(a); System.out.println(”main方法中的age=”+a.age); } } class A{ public int age = 0; } 运行结果如下:

test1方法中的age=20 main方法中的age=20 本词条内容贡献者为:

李嘉骞 - 博士 - 同济大学