通过引用调用和按值调用返回有什么区别

时间:2013-08-22 12:16:35

标签: memory-management parameter-passing computer-science

正如标题所说,我对“按引用调用”和“按值调用返回”之间的区别感到好奇。我在一些文献中读过它,并试图在互联网上找到更多的信息,但我只找到了“按值调用”和“按引用调用”的比较。

我确实理解了内存级别的差异,但两者之间并没有“概念”级别。

被调用的子程序将拥有它自己的实际参数值的副本,但是当它结束执行时,将新的本地值(绑定到形式参数)复制回调用者的实际参数。 / p>

什么时候按值调用返回实际上更喜欢上面的“按引用调用”?任何示例场景?我只能看到,由于存储单元中的值复制,需要额外的内存和执行时间。

作为一个附带问题,用“现代”语言实现的“按价值回报”是什么?

3 个答案:

答案 0 :(得分:2)

来自Wikipedia的价值回报:

  

此变体在多处理上下文和远程过程调用中受到关注:如果函数调用的参数是可由另一个执行线程访问的引用,则其内容可以复制到不是的新引用;当函数调用返回时,此新引用的更新内容将被复制回原始引用("已恢复")。

因此,从更实际的角度来看,变量在函数执行过程中处于某种不希望的状态是完全可能的。使用并行处理这是一个问题,因为您可以尝试在具有此值的情况下访问该变量。将其复制到临时值可以避免此问题。

举个例子:

policeCount = 0

everyTimeSomeoneApproachesOrLeaves()
  calculatePoliceCount(policeCount)

calculatePoliceCount(count)
  count = 0
  for each police official
    count++

goAboutMyDay()
  if policeCount == 0
    doSomethingIllegal()
  else
    doSomethingElse()

假设everyTimeSomeoneApproachesOrLeavesgoAboutMyDay并行执行。

因此,如果您通过引用传递,您可能会在policeCount中将calculatePoliceCount设置为0之后立即获取,即使周围有警察官员,那么您最终会做一些非法的事情,可能会入狱,或至少咳嗽一些钱来贿赂。如果你通过价值回报,这不会发生。

支持的语言?

在我的搜索中,我发现Ada和Fortran支持这一点。我不了解其他人。

答案 1 :(得分:0)

假设您有一个按引用调用的函数(在C ++中):

void foobar(int &x, int &y) {
   while (y-->0) {
        x++;
   }
}

然后您这样称呼:

int z = 5;
foobar(z, z);

它永远不会终止,因为xy是相同的引用,每次您递减y时,该引用随后便被撤消x的增量(因为他们都是真正的z

通过按值返回(在生锈的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,这取决于首先应用哪个结果(我不记得是否需要特定的顺序,而我无法在线找到问题的任何快速解答)。

答案 2 :(得分:-2)

请转到以下链接,那里的程序可以给你一个关于这两个的实用想法。

Difference between call-by-reference and call-by-value