关于一道php运算优先级的问题

Posted by Chen Blog on June 29, 2018

在一个群里面突然有一个同学问起这题。我看了一下。结果我也做错了。然后就认真研究了一下。

题目

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

对题解析

这一道题考了PHP运算的优先级问题。还考了前置++和后置++的关系。
在下面说一下答案

解题思路

php.net参考资料

  1. 第一次解题 (错误)
    1
    2
    3
    4
    5
    6
    
    $a = 10;
    $b = $a + ++$a + $a + ++$a;
    //因为++是先把变量+1再拿来运算。我想着结果是不是这样?
    $b = 10 + 11 + 11 + 12;
    echo $b;
    // 结果=44   这个结果是错误的
    
  2. 第二次解题 (错误)
    1
    2
    3
    4
    5
    6
    7
    8
    
    $a = 10;
    $b = $a + ++$a + $a + ++$a;
    //因为++的优先级比+要高。那么是不是先把运算里面的++先算了。在计算啊?
    //第一个12 是因为有两次++$a 那么两次就变成了12  
    //第二个11 是因为那是第一次 ++$a
    $b = 12 + 11 + 12 + 12;
    echo $b;
    // 结果=47   这个结果也是错误的
    
  3. 第三次解题

    为什么还是不正确啦?到底是我哪里想错了? 我要用PHP的运算来测试一下

    1
    2
    3
    4
    5
    6
    7
    8
    
    $a = 10;
    $b = $a + $a + ++$a;
    echo $b;
    结果既然是 31为什么嘞
    $a = 10;
    $b = $a + ++$a + $a;
    echo $b;
    结果是 33; 这又是为什么嘞不符合逻辑啊
    
  4. 认真思考之后

    我好像忽略了非常重要的一个问题。就是运算是从左到右的。 虽然++的优先级较高。但是程序从左算到右。我都还没看到你。你优先级高有什么用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    $a = 10;
    $b = $a + ++$a + $a + ++$a;
    //从左到右考了一遍
    $b = $a + ++$a    //程序先看到这个;  但是++的优先级较高。所以就把数值+1先
    $b = 11 + 11 + $a;  //这个$a已经变成11了。来。一起加上
    $b = 11 + 11 + 11 + ++$a;   //这里又碰到一个++$a哦?是不是应该先算它啊?
    //其实是这样的
    $b = 11 + 11 + 11 + 12;
    echo $b;
    //最后的结果是 45
    
  5. 来一遍完全正确的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    $a = 10;
    $b = $a + ++$a + $a + ++$a;
    //程序其实是这样计算的
    $b = $a + ++$a; 
    //先算++$a;
    $b = 11 + 11;   //11 + 11 = 22
    $b = 22 + $a;   //22 + 11 = 33
    $b = 33 + ++$a; //又来一个++$a;刚才$a已经变成了11现在++$a那就变成了12
    $b = 33 + 12;
    $b = 45;
    //最后的运算结果就是45了  终于搞明白了
    

题目扩展加深

  1. 第一次加深,考虑后置++和()

    我都怀疑我自己是不是有病了。这种题,都被我想出来?乱搞 这里需要考虑到 + 前置++ 和 后置++ 和 ()的优先级

    1
    2
    3
    4
    5
    6
    7
    
    $a = 10;
    $b = $a + ($a++ - $a + ++$a);
    $b = $a + ();   //因为()的优先级较高。所以先要把()里面计算了
    $b = $a + (10 - 11 + 12);   //因为是后置++所以是先使用10然后这个数才变成11第二次用它就是-$a那么就是-11。然后遇到前置++,那么就得把11+1=12.最终就是  10-11+12  。记住,现在$a已经变成了12了
    $b = 12 + (10 - 11 + 12);
    $b = 12 + 11;   
    $b = 23;
    
  2. 再次加深

    疯狂的我,自己都可怕了。我真的是闲得蛋疼。想出这些奇葩的题

    1
    2
    3
    4
    5
    
    $a = 10;
    $b = $a + ($a++ - $a + ++$a) > $a++ ? ++$a : --$a;
    $b = $a + (10 - 11 + 12);   //12 + (10 - 11 + 12) = 23;
    $b = 23 > 12 ? 14 : 12;
    $b = 14;
    

总结

运算是从左往右的。碰到运算符就把前后的拿来运算。但是如果后面的优先级比前面高。就要把后面的先算出来。在加上前面的。 运算的时候充分考虑优先级。