今天群里有个人问了一个问题,代码如下:
$a = 3;
$b = 2;
if ($a = 2 || $b = 5) {
    ++$a;
}
echo $a;
说代码段的执行的结果为1,问大家$a的值为什么不是3。
我看到这段代码后,和提问者的想法一样,也以为$a的值应该是3。
然后就有人说了,因为 | | 的优先级高于 = ,所以($a = 2 || $b = 5)应该写成($a = ( 2 || $b = 5)),
( 2 || $b = 5)的“或”运算结果为True,将它赋值给变量a,所以$a的值为1。
 
兴趣上来后,我就顺手打印了一下变量b的值,发现变量b的值为2。为什么变量b没有被赋值呢?有人提出了一个概念叫“短路求值”。
“短路求值”的定义如下:
作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值(short-circuit evaluation)。
假如expr1和expr2都是表达式,expr2是否求值视expr1而定:
expr1 || expr2:
    expr1的值为1,则expr2将不会进行求值。
expr1 && expr2:
    expr1的值为0,则expr2将不会进行求值。
因为( 2 || $b = 5)中,先进行2的“或”运算,结果为真,则 | | 后面$b = 5的赋值操作就不再执行了。
 
如果将 | | 前面的 2 改成 0:
$a = 3;
$b = 2;
if ($a = 0 || $b = 5) {
    echo $b;    // 5
}
echo $a;    // 1
$b的值就是5了,因为 0 的“或”运算结果为假,则后面会将5赋值给变量b,又因为“或”运算是只要两个表达式有一个为真,其结果就为真,所以$a的值仍为1。
 
那么,再将 | | 改成 &&:
$a = 3;
$b = 2;
if ($a = 0 && $b = 5) {
    var_dump($b);    // &&后面对b的赋值操作不进行,所以无输出
}
var_dump($a);    // false
echo $b;        // 2
因为0 的“与”运算结果为假,则&&后面不会再将5赋值给变量b,
又因为“与”运算是只要两个表达式有一个为假,其结果就为假,所以$a的值为0。
 
题外话:这道题虽然看起来很简单,但是经过群里“吃瓜群众”的讨论和讲解,我收获很多。尤其是我在群里说“明白了”后,那个提问者还加了我微信,和我探讨。非常佩服对方的钻研精神,如果我将这种钻研精神用到工作和学习中,想必进展一定会大大的。还要更努力哟~

一道PHP题引出的“短路求值”的更多相关文章

  1. 一个短路求值引起的一个小bug

    今天在写一个判断字符串是否回文时因为短路求值问题导致了一个bug,记录如下: 代码如下 bool isPal(char str[],int len) { int begin=0; int end=le ...

  2. C 语言 - 逻辑运算和短路求值

    逻辑运算符: 运算符 含义 优先级 ! 逻辑非 高 && 逻辑与 中 || 逻辑或 低 举例: !a:如果 a 为真,!a 为假:如果 a 为 假,!a 为真 a && ...

  3. Julia - 短路求值

    && 和 || 的布尔运算符被称为短路求值 它们连接一系列布尔表达式,仅计算最少的表达式来确定整个链的布尔值 在表达式 a && b 中,只有 a 为 true 时才计 ...

  4. php实现用短路求值原理求1+2+3+...+n(短路求值是什么)(仔细分析题干)

    php实现用短路求值原理求1+2+3+...+n(短路求值是什么)(仔细分析题干) 一.总结 1.仔细分析题干,找出要点:该递归还是得递归啊 2.短路求值原理:&&就是逻辑与,逻辑与有 ...

  5. js 实用技巧 短路求值

    &&运算符  如果操作有false  则返回false  例如 0&&1  // 返回0 true&&false  //返回false 0&&a ...

  6. 【python】Leetcode每日一题-逆波兰表达式求值

    [python]Leetcode每日一题-逆波兰表达式求值 [题目描述] 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说 ...

  7. “短路求值(Short-Circuit Evaluation)

        // 逻辑与和逻辑或操作符总是先计算其做操作数,只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数. function aa() { if (null) { console ...

  8. Matrix Chain Multiplication(表达式求值用栈操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082 Matrix Chain Multiplication Time Limit: 2000/100 ...

  9. C语言对表达式的求值顺序不是明确规定的

    讨论区看到的 WA来自那些递归下降求解的代码. 第一种情况,使用|| 和 &&: 例如s为所给串 int getval() { switch(s[c_s++]) { case 'p': ...

随机推荐

  1. 一个 xxx is not defined 引发的爬坑之路

    出处 https://www.cnblogs.com/daysme/ - 2018-01-06 昨晚找了一个代码解决了我对配置的需求.高兴的拿到手机上测试却发现点击没有效果,电脑上是可以的呀,电脑上的 ...

  2. 4、Python中的类详解(0601)

    <大话数据结构>的作者程杰在博客园也有博客,网址是:http://cj723.cnblogs.com/ 面向对象编程(OOP) 1.程序 = 指令 + 数据 代码可以选择以指令为核心或以数 ...

  3. Java 数据库篇

    一.简易封装JDBC工具类: package com.jackie.MyBatis.main; import java.sql.Connection; import java.sql.DriverMa ...

  4. oracle 与其他数据库如mysql的区别

    想明白一个问题:(1)oracle是以数据库为中心,一个数据库就是一个域(可以看作是一个文件夹的概念),一个数据库可以有多个用户,创建用户是在登陆数据库之后进行的,但是有表空间的概念(2)而mysql ...

  5. RN 使用第三方组件之react-native-image-picker(拍照/从相册获取图片)

    首先给个github地址:https://github.com/react-community/react-native-image-picker  英文不行的看下面这个笔记 该插件可以同时给iOS和 ...

  6. 【BZOJ】1875: [SDOI2009]HH去散步

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1875 注意的是路径不可以重复,所以这题把边看成点.每一条无向边拆成两条有向边. 令${F[ ...

  7. oracle的批量操作sql语句

    1.批量删除/批量更新 mapper: <update id="updatePrjStateByFPrjId" parameterType="string" ...

  8. [HTML]js读取XML文件并解析

    xml文件:test.xml <?xml version="1.0"?> <note> <to>George</to> <fr ...

  9. 《剑指offer》第五十六题(数组中唯一只出现一次的数字)

    // 面试题56(二):数组中唯一只出现一次的数字 // 题目:在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次.请 // 找出那个吃出现一次的数字. #include <iostr ...

  10. Codeforces 932D - Tree

    932D - Tree 思路: 树上倍增 anc[i][u]:u的2^i祖先 mx[i][u]:u到它的2^i祖先之间的最大值,不包括u pre[i][u]:以u开始的递增序列的2^i祖先 sum[i ...