正如标题所说,我对“按引用调用”和“按值调用返回”之间的区别感到好奇。我在一些文献中已经读过它,并试图在互联网上找到更多的信息,但我只找到了“按价值调用”和“按引用调用”的比较。
我确实理解了内存级别的差异,但不是两者之间的“概念”级别。
被调用的子程序将拥有它自己的实际参数值的副本,但是当它结束执行时,将新的本地值(绑定到形式参数)复制回调用者的实际参数。
什么时候按值调用返回实际上更喜欢“按引用调用”?任何示例场景?我只能看到,由于存储单元中的值复制,需要额外的内存和执行时间。
作为一个侧面问题,“现代”语言实施的“按价值回报”是什么?
来自Wikipedia的价值回报:
此变体在多处理上下文和远程过程调用中引起了注意:如果函数调用的参数是可能由另一个执行线程访问的引用,则其内容可能被复制到不是的新引用;当函数调用返回时,此新引用的更新内容将被复制回原始引用(“已恢复”)。
因此,在更实际的术语中,变量在函数执行过程中处于某种不期望的状态是完全可能的。使用并行处理这是一个问题,因为您可以尝试在具有此值的情况下访问该变量。将其复制到临时值可以避免此问题。
举个例子:
policeCount = 0
everyTimeSomeoneApproachesOrLeaves()
calculatePoliceCount(policeCount)
calculatePoliceCount(count)
count = 0
for each police official
count++
goAboutMyDay()
if policeCount == 0
doSomethingIllegal()
else
doSomethingElse()
假设everyTimeSomeoneApproachesOrLeaves
和goAboutMyDay
并行执行。
因此,如果你通过引用传递,你最终可能会在policeCount
设置为0后立即获得calculatePoliceCount
,即使周围有警察官员,那么你最终会做一些违法的事情,可能会入狱,或者至少咳嗽贿赂一些钱。如果您通过值返回,则不会发生这种情况。
支持的语言?
在我的搜索中,我发现Ada和Fortran支持这一点。我不认识别人。
假设您有一个按引用函数调用(在C ++中):
void foobar(int &x, int &y) {
while (y-->0) {
x++;
}
}
你这么称呼它:
int z = 5;
foobar(z, z);
它将永远不会终止,因为x
和y
是相同的参考,每次你减少y
,随后由x
的增量(因为他们都真的z
引擎盖)松开。
相比之下,使用call-by-value-return(在生锈的Fortran中):
subroutine foobar(x,y):
integer, intent(inout) :: x,y
do while y > 0:
y = y - 1
x = x + 1
end do
end subroutine foobar
如果使用相同的变量调用此例程:
integer, z = 5
call foobar(z,z)
它仍将终止,最后z
将被更改为10或0的值,具体取决于首先应用的结果(我不记得是否需要特定订单,我找不到任何快速答案在线问题)。
请转到以下链接,那里的程序可以给你一个关于这两个的实用想法。