今天群里有个人问了一个问题,代码如下:
$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. 3D场景鼠标点选择物体

    对于以下几种选择: (1)点云: (2)线框: (3)网格: 针对以上准备三个函数: (1)获取点和线段最短距离函数: (2)获取线段和线段最短距离函数: (3)获取三角面片和线段最短距离函数: 算法 ...

  2. [UVA-11100] The Trip

    题目大意 大箱子能装小箱子,求在满足最少箱子的情况下,最小化每个箱子中最大的箱子个数. 解析 想到二分枚举箱子数,然后贪心的选择放进箱子的位置. 最优策略一定是将最大的 \(m\) 个先找出来,然后把 ...

  3. jenkins+ant+jmeter自动化性能测试平台

    jenkins+ant+jmeter自动化性能测试平台 Jmeter是性能测试的工具,java编写.开源,小巧方便,可以图形界面运行也可以在命令行下运行.网上已经有人使用ant来运行,http://w ...

  4. C语言 深入学习

    浮点数: x = Mx*2^Ex为一个规格化浮点数,Mx为x的尾数,Ex为x的阶码. 1e-6:表示1 * 10 ^ (-6). 编译时执行: sizeof是运算符(而非函数),在编译时执行,不会导致 ...

  5. Windows下及Mac下的IntelliJ IDEA快捷键

    Mac 键盘符号说明 ⌘ == Command ⇧ == Shift ⇪ == Caps Lock ⌥ == Option ⌃ == Control ↩ == Return/Enter ⌫ == De ...

  6. 使用bat文件执行sql文件

    test.bat mysql -uroot -p[password] < test.sql pause test.sql CREATE DATABASE IF NOT EXISTS test_d ...

  7. es6 Set 结合 Array.from 用法

    var arr=[1,2,3,2,3,4,5]; var set=new Set(arr) var arr1=Array.from(set) 重复数组  -  Set 化 (去重) - 转回数组 上述 ...

  8. mint fcitx搜狗输入法不显示输入框,其他输入法丢失皮肤

    mint18.3 因为这个原因刚刚重装过,结果一不留神又这样了. 这次原因相对清晰: 双屏显示下,合屏睡眠,打开之后,发现卡死了.屏幕分辨率改变了似的. 然后再重启,发现输入法悬浮框变大了,然后输入法 ...

  9. 虚拟机上自动化部署(EFI网络安装)ESXi服务器遇到的问题

    1,虚拟机的CPU为2核或以上. 2,虚拟机选项中不选择: 启用UEFI安全引导.3,引导延迟:设置3000毫秒或以上 4,#GP Exception 13 in world 1:unknown @ ...

  10. Windows下tomcat启动一闪而过

    1.用记事本打开tomcat/bin/setclasspath.bat 2.添加两行代码,jdk和jre的根目录,相当于直接给出JAVA_HOME和JRE_HOME路径 set JRE_HOME=D: ...