问题表达式:
int x,i=0,j=1;
x=i++||j&&i;
输出结果:x=1
int x,i=0,j=1;
i++&&1&&1&&i;
输出结果:x=0
问题描述:
结果为1,如果++表达式的优先级真的降低了,那么应该最后运行++,结果应该是由右面的&&短路运算得到0,可是显然表达式的值为1,由此可见++的优先级并没有降低,但是还有另一个表达式的结果却又无法解释了。如果++运算符的优先级未变那么表达式的值应该是1,可是结果显然为0。
问题解释:
之所以出现这样一个结果的解释只有一个,那就是,++的优先级并没有变化,但是它是先赋值再自增。这里的赋值是指参与附近最高优先级和最近的结合性的表达式,但是变量本身是已经自增了的。拿i++||j&&i;来说。它实际执行过程如下:首先i++执行,但是i的一个早期副本i=0留了下来准备与||j&&i运算,但是i本身已经++了,然后根据优先级,&&首先运算此时的i为更新后的i所以j&&i等价于1&&1结果为1然后再与i的早期副本进行||运算在这里等价于0||1。如何证明i只是留下的副本呢?这里我们不打算从编译原理以及汇编的角度解释,我们从逻辑上来的到证明。现在看第二个表达式(以后我会总结如何通过缜密的逻辑证明事件) i++&&1&&1&&i如果i不是副本那么先执行i++得到i=1,然后执行i&&1得1以此类推最后答案一定是1,但是实际结果为0,因为逻辑运算符没有赋值功能本质上他们是取了变量的副本进行的计算,所以虽然i =1,但是参与i&&1的仍然是i的早期副本。为什么呢因为i++首先执行赋值运算,这里的赋值是指使用i的值,所以i的值优先被&&运算符复制走了早期副本i=0。
总结:
i++语句首先拿i的早期副本参与其他运算然后i=i+1,再除了i++这一句之外其他的i都是i+1的数值。(这里与电脑运算数值的顺序有关,栈结构,有兴趣的可以自行查询相关资料)。
NightPoetry
胡兵
2019/11/13