一道PHP题引出的“短路求值”

今天群里有个人问了一个问题,代码如下:
$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手册的http://www.php.net/manual/zh/language.operators.precedence.php
posted @   鹿呦呦  阅读(541)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩