今天群里有个人问了一个问题,代码如下:
$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. 【转载】常用 Java 静态代码分析工具的分析与比较

    摘自:http://www.oschina.net/question/129540_23043常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后 ...

  2. AngularJS 笔记1

    2017-03-23 本文更新链接: http://www.cnblogs.com/daysme/p/6606805.html 什么是 angularjs 2009年有两个外国人创建,后由谷歌收购并开 ...

  3. 深究CSS中Position的属性和特性

    一.position的概念 作为布局必不可缺少的元素之一,深究其属性以及一些注意点是非常必要的. 定义:规定元素的定位类型. position属性: 属性 描述 常用性 absolute 生成绝对定位 ...

  4. centos6.6 安装MariaDB

    参考文章:yum安装MariaDB(使用国内镜像快速安装,三分钟安装完毕) 安装环境: virtualbox下CentOS6.6(32位) 遇到的问题: 通过Maria官方提供的安装方式,源是国外的源 ...

  5. python字符串用法

    一,数据类型的转换 1常用的数据类型有int,str,bool三种; int是整型:一般的操作是查找数据的二进制长度bit_length() 一般数据有: 1)二进制:逢二进一 2)十进制,(0-9) ...

  6. 服务器不能设置内容类型HTTP头信息后发送

    昨天一个用户反映,导出excel失败,我测试了一下,数据量小没有问题,数据量稍微大就会出现这个问题.咨询度娘也没有找到合适的解决方法,突然想到系统中,其他模块有下载excel附件的功能,但是从没有出现 ...

  7. 负数字符串经过int处理之后还是负数

    <?php $v = '-1'; $b = (int)$v; echo $b;

  8. java之双缓冲的代码粘贴

    private Image offScreenImage = null; public void update(Graphics g) { if(offScreenImage == null) off ...

  9. 【转】Qt鼠标键盘事件

    http://blog.csdn.net/lovebird_27/article/details/50351336 Qt 程序需要在main()函数创建一个QCoreApplication对象,然后调 ...

  10. Windows下的Python 3.6.1的下载与安装(适合32bits和64bits)(图文详解)

    不多说,直接上干货! 为什么,这么简单的一个python,我还要特意来写一篇博客呢? 是因为留念下,在使用了Anaconda2和Anaconda3的基础上,现在需安装python3.6.0来做数据分析 ...