C语言中的 ++x || ++y && z++ 是如何执行的?

测试例题

#include <stdio.h>

void main() {
    int x = 2, y = 2, z = 0, a;
    a = ++x || ++y && z++;
    printf("%d,%d,%d", x, y, z);
}

运行结果

3,2,0

问题本质
a+b && b*c

你看这道表达式,你说下它的求值顺序,我猜你肯定会说:先算乘法,再算加法,最后算&&运算

而事实上,计算机在执行代码的时候并不是这样执行的,你想啊,计算机就是一个机器,它哪里知道,哪一个表达式是要先计算的

所以在计算机执行代码时,所有表达式的求值都是从左向右运算的

那你可能会问,那优先级是干嘛的,不就是区分先执行那一个后执行哪一个的嘛?

还真不是,由于表达式有多种运算,不同的结合顺序可能得出不同结果甚至出现错误运算错误

所以必须按一定顺序进行结合,才能保证运算的合理性和结果的正确性、唯一性

你可以把优先级想象成谁跟谁在一块,而不是优先级最高的最先计算

上边的那个式子,在程序执行中,会被处理成等价的语句

( a+b) && (b*c)

它是怎么执行的呢?刚才说了,由于计算机是死脑筋,只会从左向右计算表达式的值,这是规定(就是这么设计的)

所以:

第一步:先执行&&运算,因为当前的表达式是 (…) &&(…)

第二步:在执行时发现&&的左边有一个括号,那就先算括号里的子表达式的值,a+b

第三步:然后计算右边的括号的子表达式的值,也就是b*c

第四步:当执行完 第二步 和 第三步,运算两边的子表达式值就计算出来了,此时,&&运算就可以执行了

因此,我们可以都得到一个结论:优先级与求值顺序无关。如a+b && b*c,虽然 * 优先级最高,但这个表达式求值顺序是从左到右

而这道题,a = ++x || ++y && z++; 其实是一样的,虽然&&运算符的优先级大于||运算符,但这并不意味着要先执行&&运算,因为计算机它也不知道哪个表达式先执行,它只会从左向右依次运算值

计算机在运行时就根据优先级的结合,处理为等价的语句,a =( (++x) || (++y && z++) );

由于计算机是死脑筋,表达式求值,从左向右进行

第一步:先计算=这个赋值运算,但是,发现右边是一个表达式

第二步:计算机先停下来赋值运算,转去计算右边的复合表达式( (++x) || (++y && z++) )

第三步:此时又发现这是一个||运算,又分为了左右两边两个子表达式,怎么办,我先计算子表达式的值

第四步:计算(++x),咦,我发现++x后,这个表达式的值是3,在C语言中,非0即真,并且这是一个或运算,有一得一,后边的表达式我就不用算了,偷个懒,计算机也很累的

第五步:||运算后的表达式值为1,将 ( (++x) || (++y && z++) ) 表达式的值1赋值给变量a,这样就完成了这条语句的执行

注意:我们犯的错误就是,主观的认为,我们人类怎么计算,计算机就是怎么计算,我们没有考虑计算机的感受,它看不懂这么复杂的表达式

只能做一些简单的重复性工作,别的不会,从左向右一个一个算,这我倒是会的,那我就这么来,而优先级说白了就是给这个表达式划分括号的

猜你喜欢

转载自blog.csdn.net/qq_38490457/article/details/105936159