Nea*_*eal 65 php math operator-precedence
如果我试试这个:
$a = 0;
echo $a + ++$a, PHP_EOL;
echo $a;
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
2
1
Run Code Online (Sandbox Code Playgroud)
演示:http://codepad.org/ncVuJtJu
我希望得到这个作为输出:
1
1
Run Code Online (Sandbox Code Playgroud)
$a = 0; // a === 0
echo $a + ++$a, PHP_EOL; // (0) + (0+1) === 1
echo $a; // a === 1
Run Code Online (Sandbox Code Playgroud)
但为什么输出不是这样呢?
int*_*jay 113
解释为什么你得到2而不是1的所有答案实际上都是错误的.根据PHP文档,混合+
并++
以这种方式是未定义的行为,因此您可以获得1或2.切换到不同版本的PHP可能会更改您获得的结果,并且它将同样有效.
参见示例1,其中说:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
Run Code Online (Sandbox Code Playgroud)
笔记:
运算符优先级并不能确定评价的顺序.运算符优先级仅确定表达式$l + ++$l
被解析为$l + (++$l)
,但不确定是否+
首先计算运算符的左或右操作数.如果首先计算左操作数,则结果为0 + 1,如果首先计算右操作数,则结果为1 + 1.
操作员关联性也不确定评估顺序.该+
操作者已经离开结合性仅确定$a+$b+$c
为被评估($a+$b)+$c
.它不确定单个运算符的操作数的评估顺序.
同样相关:关于另一个带有未定义结果的表达式的错误报告,PHP开发人员说:"我们不保证评估的顺序[...],就像C没有.你能指出任何地方吗?说明首先评估第一个操作数的文档?"
Den*_*nis 66
preincrement运算符"++"发生在它所评估的表达式的其余部分之前.实际上它是:
echo $l + ++$l; // (1) + (0+1) === 2
Run Code Online (Sandbox Code Playgroud)
hak*_*kre 24
a + b
a = 1
b = ++a
:= 2
Run Code Online (Sandbox Code Playgroud)
你为什么期待别的什么?
在PHP中:
$a = 0;
$c = $a + ++$a;
Run Code Online (Sandbox Code Playgroud)
运算符优先级可视化:
$c = ($a) + (++$a);
Run Code Online (Sandbox Code Playgroud)
评估序列可视化:
$a = 0; ($a = 0)
$a = 1; (++$a)
$c = $a + $a (1 + 1);
Run Code Online (Sandbox Code Playgroud)
或写出来:
执行总和操作的时刻$a
已经是1,因为++$a
已经进行了评估.在++
该操作前评估+
操作.
为了好玩:
$a++ + ++$a
Run Code Online (Sandbox Code Playgroud)
结果也是2.但是,如果将其作为表达式进行比较,则不等于:
$a++ + ++$a == $a + ++$a
Run Code Online (Sandbox Code Playgroud)
在哪里
$a++ + ++$a == $a-- + --$a
Run Code Online (Sandbox Code Playgroud)
是平等的".
也可以看看:
我在PHP博客文章中的评估订单详细解释了这一点,但这里是基本的想法:
$a
)除外.对更简单的变量的访问将在更复杂的表达式之后执行,无论表达式实际发生的顺序如何.++$a
首先运行,因为它是一个复杂的表达式,然后才$a
获取值(此时它已经是1).所以你有效地总结1 + 1 = 2
.@
错误抑制运算符,则从左到右计算所有表达式,包括简单变量提取.@($a + ++$a)
将导致1
,因为首先$a
获取(当时为0)并且仅在此之后递增.++
是优先级较高的运算符,因此首先应用它.
所以现在 l = 1.
所以 1 + 1 = 2.