5

这可能算不上是一次正规的解说,毕竟有点烧脑。

起因

是这样的,我们都知道php语法里有自增操作,即 ++,那么下面我列出一个表达式

$a = 1;
$result = $a  +  $a++; // $result === 3

好的,为什么等于3?只有一种解释,就是自增的优先级高于加减,所以二号位自增导致了一号位也变成2。(3 = 2 + 1)

既然一号位变成了2,为何二号位不会变成2呢?因为后置自增的返回值仅是临时变量,这点和 C/C++是一致的,毕竟PHP也是基于C实现的。


换个写法

$a = 1;
$result = $a  +  ++$a; // $result === 4

似乎验证了刚才的解释。由于是前置自增,所以二号位自己的值也变成了2。(4 = 2 + 2)

恶化

接下来,我们把数量增加到3个

$a = 1;
$result = $a  +  ++$a  +  ++$a;  // $result === 7

为什么是7?按照思路,应该是 9 = 3 + 3 + 3,也是醉了,并没有按照常理出牌。


增加到4个呢

$a = 1;
$result = $a  +  ++$a  +  ++$a + ++$a;  // $result === 11

答案也不是 16 = 4 + 4 + 4 + 4,好吧,和我想的不一样。

猜测

既然2个$a相加可以正确推算,而3个开始就出错,为何?于是有了一个猜测,PHP是这样相加的

$a = 1;
$result = ( ( $a  +  ++$a )   +  ++$a )  +  ++$a; // $result === 11

优先级顺序 () > ++ > +,11 = ( ( 2 + 2 ) + 3 ) + 4,每跳出一层,$a都自增了1。
有括号和没有括号的运算,最终运算结果都是11,我有点确信隐形括号这个事实。

隐形括号

于是我只让最后一个$a是自增的

$a = 1;
$result_a = $a  +  $a   +  $a   +  ++$a;  // $result_a === 5

$a = 1;
$result_b = ( ( $a  +  $a)  +  $a )  +  ++$a;  // $result_b === 5

好的,$result_a 和 $result_b 的值是一样的。5 = ( ( 1 + 1 ) + 1 ) + 2


我们此时加入后置自增,看看结果会不会一样

$a = 1;
$result_a = $a  +  $a   +  $a++   +  ++$a;  // $result_a === 6

$a = 1;
$result_b = ( ( $a  +  $a)  +  $a++ )  +  ++$a;  // $result_b === 6

是的,遵循了隐形括号的规则, 6 = ( ( 1 + 1) + 1 ) + 3。

诡异的1

为了给隐形括号做个最终的定论,我们再看一个烧脑例子

$a = 1;
$result_a =       $a  +  ++$a  +  ++$a; // $result_a === 7

$a = 1;
$result_b = 1  +  $a  +  ++$a  +  ++$a; // $result_b === 7

不不不,你没有看错,$result_b的前面真的多了一个1。但是,它们的值都是7。你知道为什么吗?


夜葬
3.6k 声望1.2k 粉丝

极客