不直观的表达式计算与增量

2022-08-30 11:11:35

对于以下代码

<?php

$a=1;   $b=$a++;              var_dump($b);
$a=1;   $b=$a+$a++;           var_dump($b);
$a=1;   $b=$a+$a+$a++;        var_dump($b);
$a=1;   $b=$a+$a+$a+$a++;     var_dump($b);
$a=1;   $b=$a+$a+$a+$a+$a++;  var_dump($b);

我得到了这个结果:

int(1)
int(3)
int(3)
int(4)
int(5)

我期望1,2,3,4,5而不是1,3,3,4,5。为什么在我们获得之后?$a=1; $b=$a+$a++;$b=3

PHP 7.1.5-1+deb.sury.org~xenial+1 (cli) (建制日期: May 11 2017 14:07:52) ( NTS )


答案 1
$a=1;   $b=$a+$a++;           var_dump($b);            // int(3)

假设上面的表达式从左到右计算如下(为清楚起见,在解释中引入了临时变量):$u$v

 $a = 1;
 $u = $a;              //    ($a)   the LHS operand of `+`
 $v = $a;              //  \ ($a++) the RHS operand of `+`
 $a ++;                //  /
 $b = $u + $v;         // 2 (1+1)

不能保证子表达式按指定顺序进行计算PHP运算符的文档页面指出(重点是我的):

运算符优先级和关联性仅确定表达式的分组方式,它们不指定计算顺序。PHP(在一般情况下)不指定表达式的计算顺序,并且应该避免使用假定特定计算顺序的代码,因为行为可以在PHP版本之间或取决于周围的代码而变化。

PHP 为其他表达式计算的值与您假设的值匹配,这只能偶然出现。当使用不同版本的 PHP 解释器执行代码时,它们的值可能会有所不同。


答案 2

PHP(在一般情况下)不指定表达式的计算顺序,并且应避免使用假定特定计算顺序的代码[..]

http://php.net/manual/en/language.operators.precedence.php

您得到不同结果的原因是,有时首先评估右操作数,有时计算左操作数。PHP对操作的顺序不做任何保证,所以没有正确的答案,这完全属于未定义行为的范畴。


推荐