大神们,来讨论下 $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
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 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年前 评论

卧槽 这是为啥 都是 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年前 评论

$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年前 评论

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