一个面试题造成的血案

什么称之为血案, 因为在百科内部几个程序袁之间进行了激烈的争论。

为什么称之为血案, 因为在百科内部几个程序袁之间进行了激烈的争论。

不要问我答案从哪里来,我的求解过程不是那么容易滴,

不要问我基本功如何,一样会被这道题目打败,

答案不是你想来就是你能来,给我讲讲求解过程才是我的爱。

晓晨(一脸严肃):这个题目太简单了,毫无疑问,a=6, b=8, 答案A

李静(一脸不屑):这个题必须是B,不叨叨

明川(一脸得意):表闹了(枉自你们写了这么多年的php,还不如我刚毕业的),这个题答案是E

陈健(一脸诧异 ):这样我选C(选一个你们都没有选的),C啊,赔率3.5

你走开,一个前端的导什么乱,切你的图去~~~

于是乎四人争论不止,A, 是B好不好,CC压注了啊,E是E你们这群吊丝,

正常工作无法进行怎么行,必须有人出面制止,

于是我出现了(这个题确定一定以及肯定是B,作为一个写php写的满手是茧子的我,一脸蔑视,这个题目是给刚毕业出的吧),

明川你调试下看看结果不就知道了,调试完结果我告诉你们为什么(不就是一个$a=5赋值后返回结果为true, 后面||运算符不执行,然后进入if语句各+1, 6,6吗,o了),

答案是D磊哥,靠我们都错了,磊哥帮忙解释下。。。

哦(执行出来的是什么那答案就是什么),我说吧答案是D。

为什么,为什么~~~

哦,我有点事忙上午,上线,下午告诉你们啊,稍等回。(聪明的我总能找到推脱方案,但是总归要弄明白个为什么吧,要不如何服众,水能载舟亦能覆舟,什么乱七八糟的,赶紧看看为什么)。。。

看到了答案第一感觉就是这是个涉及到运算符优先级的题目,但是要证实这个问题那我们就翻出opconde来看一看,

首先

php -dvld.active=1 -dvld.verbosity=3 test.php


(这篇文章不会多介绍opcode是什么,有兴趣单独一个课题来探讨一下)

通过opcode我可以确定"||"运算符是先执行的,为什么这么确定,我们来看 

大家看到了吧,在php语法解析时‘||'运算符对应着解析函数为zend_do_boolean_or_begin,执行的opcode即为ZEND_JMPNZ_EX。

然后大家看opcode的第一个操作数op1 是 5 ,于是茅塞顿开,原来执行顺序是这样的,现在我将代码修改为if($a = (5 || $b = 7))与我们上面的例子是等价哦!

以上是第一个比较容易迷惑的知识点,我也在这栽了跟头。

因为第一个操作数是5,所以||运算符将临时变量~2赋值为true(BOOL),返回值可以查看ZEND_JMPNZ_EX_SPEC_CONST_HANDLER句柄函数,然后掉转到行数8(即$b=7不予执行)。

在第8行看到了临时变量~2将值赋值给了$a, 再接下来执行的if语句的opcode的jmp句柄函数,发现是true于是继续往下执行而没有跳出。

再接下来很简单$a++, $b++,于是答案是2,6,我想大部分童鞋都这么认为,可是答案明明是1,6啊真是百思不得其解,挠墙。

我想这就是考验你的第二个知识点吧,于是我写了个简单的例子:<?php
$a = true;
$a++;
echo $a;

---1 输出答案是1,我找到了问题所在,bool型++后不像我们认为的true+1=2,那我们来验证一下

首先++运算符语法分析的函数是zend_do_post_incdec,其中调用的opcode句柄函数为 

竟然让我发现++操作没有针对bool型做运算,那难道做了++操作,什么都没变,还是bool吗,我们验证一下

<?php
$a =true;
++$a;
var_dump($a);exit;

---BOOL

哈哈是不是恍然大悟果然是哦,echo 输出的时候会把bool型转变为int当然就是1喽,解决了,明川来来我告诉你为啥来~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值