“按值传递参数” CLRS算法

作者所说的“表示对象的数据被复制但对象的属性没有被复制”是什么意思?有人给我举了一个例子,说明它是如何在python,java或C中实现的。


以下摘录自CLRS算法第一章。

“我们通过值将参数传递给过程:被调用过程收到其自己的参数副本,如果它为参数分配了值,则调用过程看不到更改。当对象被传递时,指向对象的数据的指针被复制,但是对象的属性没有被复制,例如,如果x是被调用过程的参数,则被调用过程看不到被调用过程中的赋值x = y。 = 3,但是是可见的。类似地,数组通过指针传递,以便传递指向数组的指针而不是整个数组,并且对单个数组元素的更改对于调用过程是可见的。

在此先感谢您为我提供帮助。

okyi1 回答:“按值传递参数” CLRS算法

这是几乎所有现代命令式编程语言的正常行为,这些命令式语言具有不变的原语和可变对象,例如Java,Python,Javascript等。我将使用Javascript作为示例,但是如果您不希望使用Javascript,那么代码足够简单,无论如何您都可以理解其解释。


请考虑以下代码,该代码声明一个变量并调用一个函数:

function foo(x) {
    x = 5;
}

var y = 2;
foo(y);
console.log(y); // outputs number 2

函数中的变量xy获取其值,但它是存储在内存中不同位置的另一个变量。因此,当函数将数字5分配给x时,数字5也被分配给yx中的更改不在函数外部“可见”。

现在考虑这段代码,本质上是相同的,只是用一个对象而不是一个数字:

function bar(x) {
    x = { a: 3,b: 4 };
}

var y = { a: 1,b: 2 };
bar(y);
console.log(y); // outputs { a: 1,b: 2 }

同样,xy(是对对象的引用)获取其值,但是为x分配新引用不会更改哪个引用{{1} }成立是因为它们存储在不同的存储位置。

现在是最后一个示例:

y

这一次函数function baz(x) { x.a = 3; x.b = 4; } var y = { a: 1,b: 2 }; baz(y); console.log(y); // outputs { a: 3,b: 4 } 确实会更改结果,因为baz持有对对象的引用,并且在调用函数时,y持有对同一对象的引用(不是对象的副本),因此对其属性的分配 在函数外部是“可见的”。


如果您觉得所有这些都简单明了,则可以忽略该段落;这只是在说明他们在书中使用的语言具有这些行为。该段的目的是阐明其语言的语义,因为并非所有语言的所有功能都以这种方式表现。

例如,在C ++中,可以这样编写xfoo,以使它们 可以“从远处”改变y的值。或者,在对象不可变的功能编程语言中,bar 不会更改对象baz,它会创建具有不同属性的新对象,而不会在函数外部可见。

因此,书中的这一段对于可能更熟悉函数参数的其他语义的读者来说是一个有用的澄清。

本文链接:https://www.f2er.com/3126951.html

大家都在问