按引用传递 vs 按值传递

3
<?php
function sum($y) {
$y = $y + 5; 
}

$x = 5;
sum($x);
echo $x;
?>

我有这段代码。问题是:它输出什么?答案是:5。如何使它输出10?答案是:sum(&$x)。

问题是我不明白为什么第一个问题的答案是5。当您使用sum($x)时,它难道不应该将函数替换为$x,因此$x = 5 + 5 = 10吗?为什么答案是5?有人向我解释了与指针和地址相关的内容,但我没有理解。我从未理解过指针的概念,我在Google上搜索了一下,显然php中没有指针,所以我非常困惑。我的朋友说,变量由一个值和该值的内存地址组成。请有人用我五岁小孩子的语言告诉我为什么答案是5而不是10?谢谢。


$x+5 的值并没有被放回到 $x 中,而是被放入了 $y 中,而 $y 只存在于 sum($y) 函数的范围内。 - x13
但是为什么会发生这种情况呢?我知道我的问题非常愚蠢。我的意思是,sum($x)不是 $x=$x+5 吗?为什么它要放回到 $y 中呢?难道 sum($x) 不是指用 $x 替换 $y 吗? - Elena Stoean
2
默认情况下,它会创建一个名为$y$x的“副本”,并在sum($y)函数中使用。此时,$x$y除了(巧合地)具有相同的值之外没有任何关联。$y增加了5,但是$x在任何地方都没有被提及。如果你将$y放在参数列表中,如sum(&$y),它不会创建一个新的副本,而是引用了$x。这就像把某人的电话号码写在便利贴上,和在便利贴上写上你可以找到他们电话号码的地方之间的区别。 - x13
2
很好,你问为什么是个好事情,不是很多程序员似乎关心为什么某些东西能够工作。 - x13
1
谢谢你给我解释,我一直想知道为什么会发生这件事。如果你告诉我它只是简单地发生了,那对我来说并不足够,哈哈。 - Elena Stoean
3个回答

6

假设$x是一张写有数字5的纸片。

function sum($y) {
  $y = $y + 5; 
}

这里的$y是您所写内容的。在您的脑海中将该值加上5,但备忘录保持不变。

function sum(&$y) {
  $y = $y + 5; 
}

通过引用运算符(&$y),您将这张纸本身传递给函数,它会覆盖上面写的内容。


对于像数字这样的原始值,我不会费心,总是返回您想要的值:

function valuePlusFive($x) {
  return $x + 5;
}

$x = 5;
$x = valuePlusFive($x);

1
ELI5已验证答案,我喜欢它。 - user1897253
现在有道理了,你和第二条评论确实让我明白了,谢谢! - Elena Stoean

5
这并不是从理论角度来看一个很好的解释,但这应该可以帮助您理解概念:
当您像这样声明函数然后调用它时:
function ($argument) {...}

您传递的参数是按值传递的。这意味着在函数范围内,您将使用传递的参数的副本进行操作。您可以想象,在调用函数之前,已经创建了参数的副本,并且在函数内部,您正在使用该副本,而原始副本保持不变。一旦函数完成,副本就不存在了。
但是,当您像这样声明时:
function (&$argument) {...}

你正在通过引用传递参数,这意味着你直接使用了传递的变量。因此,在这种情况下不会产生副本,你将参数从一个地方带入函数并对其进行了更改。

3
在PHP中,“变量的作用域是定义它的上下文。”(根据文档)。因此,在您的函数内部,$y(您传递的值的副本)正在被操作,但它没有被函数返回。因此,当函数结束时,该值不再在函数外部可访问。
如果您想要 通过引用传递变量(类似于C中的指针),则可以像这样添加一个&
function sum(&$y) {
  $y = $y + 5; 
}

现在当您调用此代码时:
$x = 5;
sum($x);
echo $x;

它将输出10。也许更好的方法是从您的函数中返回一个值,并输出该值:

function sum($y) {
  return $y + 5; 
}

$x = 5;
echo sum($x);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接