大神们,来讨论下 $a+$a++ 运算的结果

<?php
    $a = 1;
    $b = $a + $a++;
    echo $b;

    $a = 1;
    $c = $a + $a + $a++;
    echo $c;

在其它地方看到的,结果和我想的不一样,求大神解下。

Good Good Study , Day Day Up!!
Jourdon
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 10
沙渺
<?php // 为了消除对 $a 反复赋值的影响,稍微改写一下楼主位的程序
$a = 1; $b = ($a + $a++);      echo $b;
$c = 1; $d = ($c + $c + $c++); echo $d;

这就是典型的UB(undefined behavior,未定义行为)。php手册明确指出

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

简而言之:如果同一个语句中“求值”与“修改”同时出现,那么其执行顺序没有任何保证。

所以对于上边的程序,$b 得 2 或 3 都是对的,$d 得 3 或 4 都是对的。

事实上这个程序在不同的PHP版本下,就可以测试出不同的结果:
(以下结果来自于 http://sandbox.onlinephpfunctions.com/

  • 对于 PHP 7.1.0 ,$b 得 3 ,$d 得 3
  • 对于 PHP 4.4.9 ,$b 得 2 ,$d 得 3
6年前 评论
沙渺
<?php // 为了消除对 $a 反复赋值的影响,稍微改写一下楼主位的程序
$a = 1; $b = ($a + $a++);      echo $b;
$c = 1; $d = ($c + $c + $c++); echo $d;

这就是典型的UB(undefined behavior,未定义行为)。php手册明确指出

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

简而言之:如果同一个语句中“求值”与“修改”同时出现,那么其执行顺序没有任何保证。

所以对于上边的程序,$b 得 2 或 3 都是对的,$d 得 3 或 4 都是对的。

事实上这个程序在不同的PHP版本下,就可以测试出不同的结果:
(以下结果来自于 http://sandbox.onlinephpfunctions.com/

  • 对于 PHP 7.1.0 ,$b 得 3 ,$d 得 3
  • 对于 PHP 4.4.9 ,$b 得 2 ,$d 得 3
6年前 评论
沙渺

简而言之,最终的结论:

  1. 一条语句不应当同时 ①取变量值 ②对变量产生副作用(更改、赋值等)。
  2. 只有极为简单的情况下可以容忍,例如$r = $a++;。但这个实践仍然不良,最好改掉。
6年前 评论

卧槽 这是为啥 都是 3

6年前 评论

$a = 1;
$b = $a + $a++;
$b = 2 + 1;
echo $b;

$a = 1;
$c = $a + $a + $a++;
$c = 2 + 2+ 1;
echo $c;

????

6年前 评论
Jourdon

@沙渺 执行顺序不能保证我不太理解,简单说不是从上到下吗?

6年前 评论
沙渺

@王东哲 指的是一条语句之内,各个部分的执行顺序。例如 $b = $a + $a++; 这一条语句就有4个行为:

  1. +左侧的值:取$a
  2. +右侧的值:取$a,之后$a自增
  3. 运算
  4. $b赋值。

其中只有3和4的顺序是确定的,1、2的顺序不能保证。

6年前 评论
Jourdon

@沙渺 谢谢,明白了

6年前 评论
chongyi

官方文档有说明

6年前 评论

面试题碰到这个就 gg 了

6年前 评论

@mingyun 面试碰到这种题目,难道不是扭头就走吗?

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!