如果我试试这个:
$a = 0;
echo $a + ++$a, PHP_EOL;
echo $a;
我得到了这个输出:
2
1
演示:http://codepad.org/ncVuJtJu
我希望将此作为输出:
1
1
$a = 0; // a === 0
echo $a + ++$a, PHP_EOL; // (0) + (0+1) === 1
echo $a; // a === 1
但为什么不是输出?
答案 0 :(得分:112)
解释为什么你得到2而不是1的所有答案实际上都是错误的。根据PHP文档,以这种方式混合+
和++
是未定义的行为,因此您可以获得1或2.切换到不同版本的PHP可能会改变您获得的结果,并且它会同样有效。
请参阅example 1,其中包含:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
注意:
运算符优先级不确定评估顺序。运算符优先级仅确定表达式$l + ++$l
被解析为$l + (++$l)
,但不确定是否首先计算+
运算符的左或右操作数。如果首先计算左操作数,则结果为0 + 1,如果首先计算右操作数,则结果为1 + 1.
操作员关联性也不确定评估顺序。 +
运算符左侧关联性仅确定$a+$b+$c
被评估为($a+$b)+$c
。它不确定单个运算符的操作数的评估顺序。
同样相关:在this bug report关于另一个带有未定义结果的表达式,PHP开发人员说:“我们不保证评估的顺序[...],就像C没有。你能指出吗?到文档的任何地方,表明首先评估第一个操作数?“
答案 1 :(得分:66)
preincrement运算符“++”发生在它所评估的表达式的其余部分之前。实际上它是:
echo $l + ++$l; // (1) + (0+1) === 2
答案 2 :(得分:24)
a + b
a = 1
b = ++a
:= 2
你为什么期待别的什么?
在PHP中:
$a = 0;
$c = $a + ++$a;
$c = ($a) + (++$a);
可视化评估序列:
$a = 0; ($a = 0)
$a = 1; (++$a)
$c = $a + $a (1 + 1);
或写出:
执行求和操作的那一刻,$a
已经为1,因为++$a
已经被评估过了。 ++
运算符在+
运算符之前进行评估。
为了好玩:
$a++ + ++$a
结果也是2。但是,如果将其作为表达式进行比较,则不等于:
$a++ + ++$a == $a + ++$a
在哪里
$a++ + ++$a == $a-- + --$a
是“平等的”。
另见:
答案 3 :(得分:7)
我的Evaluation Order in PHP博文详细解释了这一点,但这里有一个基本想法:
$a
)除外。在更复杂的表达式之后,将执行对简单变量的访问,无论表达式实际发生的顺序如何。++$a
首先运行,因为它是一个复杂的表达式,然后才会获取$a
的值(此时它已经是1)。所以你有效地总结了1 + 1 = 2
。@
错误抑制运算符,则从左到右计算所有表达式,包括简单的变量提取。@($a + ++$a)
将导致1
,因为第一个$a
被提取(当时为0)并且仅在此之后递增。答案 4 :(得分:6)
++
是更高优先级的运算符,因此首先应用它。
现在l = 1.
所以1 + 1 = 2.
答案 5 :(得分:3)
当你执行++ $ l(preincrement)时,它会在你加入之前完成 - > check operator precedence)。
因此,$l
的值在您添加之前为1
:
echo $l + ++$l; // $l => 1 because ++$l is done first
所以你的答案是2。
但是当你这样做时:
echo $l // you will get your first value which is $l => 1
所以你的回答是1。
答案 6 :(得分:2)
可以通过检查PHP如何编译脚本来确认此行为,例如:
$a = 0;
echo $a + ++$a;
编译成以下操作码,然后执行:
compiled vars: !0 = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
1 0 > ASSIGN !0, 0
1 PRE_INC $1 !0
2 ADD ~2 !0, $1
3 ECHO ~2
4 > RETURN null
这转换为以下等效脚本:
$a = 0; // ASSIGN
$tmp = ++$a; // PRE_INC
echo $a + $tmp; // ADD, ECHO
<强>结论强>
当$a
被评估为$a + (++$a)
的左手表达式时,它已经递增,因为++$a
首先被评估。
显然,这种行为应not be relied upon;用这种方式的任何语言。
答案 7 :(得分:1)
检查增量操作员手册:
http://www.php.net/manual/en/language.operators.increment.php
或者看到此键盘:http://codepad.org/Y3CnhiLx
<?php
$n = 0;
$m = 0;
echo '++ before:';
echo $n+ ++$n;
echo PHP_EOL;
echo '++ after:';
echo $m+ $m++;
echo PHP_EOL;
echo 'n:'.$n;
echo PHP_EOL;
echo 'm:'.$m;
输出:
++ before:2
++ after:1
n:1
m:1
答案 8 :(得分:1)
您可能知道我们有两个增量运算符,一个是预增量,第二个是后增量。在表达式中使用之前,预增量会增加整数的值,另一方面,在表达式中使用后,增量增加值会增加。
假设您有变量$ a和变量$ b,如下所示
$ A = 0;
$ b = ++ $ a给出b = 1的值
,而
$ b = $ a ++给出值b = 0
答案 9 :(得分:1)
您的代码输出因PHP版本as seen here
而异4.3.0 - 5.0.5的输出 1
1
在上述情况下,首先评估+
运算符的左侧(0,1,+)。
5.1.0的输出 - 5.5.0alpha4
2
1
在上述情况下,首先评估+
运算符的右侧(1,1,+)。
这符合interjay's answer,在PHP中无法保证子表达式的评估顺序。输出 可能 1, 1
的假设是正确的,那么声称输出 可能的答案也是正确的 1, 2
。
答案 10 :(得分:0)
第一个显而易见的部分是++
的优先级高于+
。
第二部分是php引擎不会将第一个操作数的值存储到另一个匿名变量中。所以$l + ++$l
不是
$a = $l;
$b = ++$l;
return $a + $b;
答案 11 :(得分:0)
如前所述,x ++和++ x存在差异。你可以用
的方式解释它x++;
分号后递增
和
++x;
评估表达式时增加
所以看来你的表达式是从右到左评估的
echo $l + ++$l;
答案 12 :(得分:-2)
所有陈述均从右到左执行。 因此,该值首先递增,而变量值= 1,因此1 + 1 = 2