运算符&&和||优先级问题

时间:2020-12-27 17:23:19
#include "stdio.h"
main()
{
    int x,y,z;
    x=y=z=1;
    if(x++||y++&&z++)
        printf("\n%d,%d,%d\n",x,y,z);
}
这个程序在运行的结果是2,1,1。
可是按照书上说的&&的优先级高于||,
那样应该先 算y和z啊,如果为真应该发生短路,不算x,这样结果应该是1,2,2。
请问这是什么 原因,我理解的错误是什么地方啊

28 个解决方案

#1


我觉得跟结合性有关,
我的理解是如a+b*c那么编译起从做向右看,先判断+两边是a和b但不旁边又有操作符*所以b要先和*c结合
这里编译器先看x++执行完后变为2然后在判断,再和||(y++&&z++)结合。但x++为true所以那边就不执行了&&无论为true或false都无关了)
初学,说错了莫怪

#2


||,&&从左到右计算,||在得到true就不往后计算,&&在得到false就不往后计算

#3


正因为&&优先级高,所以先计算左边的表达式"x++ ¦ ¦y++"

#4


编译器是由左向右计算的,先看a++,为2,结果确定就不再向下计算了

#5


引用 4 楼 moonwrong 的回复:
编译器是由左向右计算的,先看a++,为2,结果确定就不再向下计算了

#6


楼上发错了
如果将x改为0,表达式的值不能确定,就要运算后者

#7


楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号.
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道.

#8


引用 7 楼 Inhibitory 的回复:
楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号. 
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道.

up,
x++¦¦y++&&z++ 
这样真的很麻烦,貌似在戏耍看代码的

#9


我来解释,||逻辑或 左右两边只要有一边为真的话,就成立.
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++
所以,Y=1.Z=1;

#10


x++ ¦ ¦ y++&&z++
编译器是这样处理表达式:用stack来存放运算符,当遇见优先级低于栈顶的运算符则出栈进行计算,两个加号进栈了,遇见了¦ ¦,则会将+ +弹出栈进行计算,并且若是为1可以直接转到下一个语句,若为0仍得判断表达式后半部分。这个就是编译原理的知识,编译器总希望更高效率进行编译的!!!!!!

#11


很明显,因为 || 运算符只要左边的表达式为true,后面的表达式就不会计算了!

所以执行X++之后,y++&&z++不会执行,x变为2, y z仍然为1

#12


该回复于2008-08-07 09:18:03被版主删除

#13


写代码尽量不要搞优先级问题,多+括号看起来也舒服

#14


()这样不为难自己也不为难别人
你好大家都好

#15


优先级体现在算到右边的时候把y++当作右侧还是把y++ && z++当作右侧,先计算左侧这一点是不受优先级影响的。

#16


引用楼主 koknine 的帖子:
#include "stdio.h" 
main() 

    int x,y,z; 
    x=y=z=1; 
    if(x++ ¦ ¦y++&&z++) 
        printf("\n%d,%d,%d\n",x,y,z); 

这个程序在运行的结果是2,1,1。 
可是按照书上说的&&的优先级高于 ¦ ¦, 
那样应该先 算y和z啊,如果为真应该发生短路,不算x,这样结果应该是1,2,2。 
请问这是什么 原因,我理解的错误是什么地方啊


对嘛!

if里面,从左到右,先看||前面的,是1,那么后面的就不会计算了!也就是不理会后面的y++ z++

所以输出是那么样子!

#17


这时编译器优化的问题。
++运算容易产生二义性。慎用!

#18


x++ ¦ ¦y++&&z++ 等价于x++ ¦ ¦(y++&&z++)
先计算 x++,x=2为真,(y++&&z++)就不在计算,所以y和z还是为1

#19


引用 15 楼 Maxwell 的回复:
优先级体现在算到右边的时候把y++当作右侧还是把y++ && z++当作右侧,先计算左侧这一点是不受优先级影响的。

#20


编译器可能优化了

可以用括号解决这样的问题

#21


我也看书上的习题,才发现的,,搞了半天不明白。

#22


引用 8 楼 moonwrong 的回复:
引用 7 楼 Inhibitory 的回复:
楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号. 
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道. 
 
up, 
x++¦¦y++&&z++ 
这样真的很麻烦,貌似在戏耍看代码的


我也是初学,做习题上机时候发现的

#23


引用楼主 koknine 的帖子:
#include "stdio.h" 
main() 

    int x,y,z; 
    x=y=z=1; 
    if(x++ ¦ ¦y++&&z++) 
        printf("\n%d,%d,%d\n",x,y,z); 

这个程序在运行的结果是2,1,1。 
可是按照书上说的&&的优先级高于 ¦ ¦, 
那样应该先 算y和z啊,如果为真应该发生短路,不算x,这样结果应该是1,2,2。 
请问这是什么 原因,我理解的错误是什么地方啊


应该是编译器优化了,即你的x++为true是||后面的值就不运算了。

#24


引用 9 楼 fansyong 的回复:
我来解释, ¦ ¦逻辑或 左右两边只要有一边为真的话,就成立. 
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++ 
所以,Y=1.Z=1;



原来是这样

#25


引用 9 楼 fansyong 的回复:
我来解释,||逻辑或 左右两边只要有一边为真的话,就成立.
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++
所以,Y=1.Z=1;

说的很好

#26


isNaN(dd.value)

#27


以后再写这样的程序不加括号的一律重写

#28


引用 23 楼 hjessica 的回复:
引用楼主 koknine 的帖子:
#include "stdio.h"
main()
{
int x,y,z;
x=y=z=1;
if(x++ ¦ ¦y++&&z++)
printf("\n%d,%d,%d\n",x,y,z);
}
这个程序在运行的结果是2,1,1。
可是按照书上说的&&的优先级高于 ¦ ¦,
那样应该先 算y和z啊,如果为……


#1


我觉得跟结合性有关,
我的理解是如a+b*c那么编译起从做向右看,先判断+两边是a和b但不旁边又有操作符*所以b要先和*c结合
这里编译器先看x++执行完后变为2然后在判断,再和||(y++&&z++)结合。但x++为true所以那边就不执行了&&无论为true或false都无关了)
初学,说错了莫怪

#2


||,&&从左到右计算,||在得到true就不往后计算,&&在得到false就不往后计算

#3


正因为&&优先级高,所以先计算左边的表达式"x++ ¦ ¦y++"

#4


编译器是由左向右计算的,先看a++,为2,结果确定就不再向下计算了

#5


引用 4 楼 moonwrong 的回复:
编译器是由左向右计算的,先看a++,为2,结果确定就不再向下计算了

#6


楼上发错了
如果将x改为0,表达式的值不能确定,就要运算后者

#7


楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号.
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道.

#8


引用 7 楼 Inhibitory 的回复:
楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号. 
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道.

up,
x++¦¦y++&&z++ 
这样真的很麻烦,貌似在戏耍看代码的

#9


我来解释,||逻辑或 左右两边只要有一边为真的话,就成立.
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++
所以,Y=1.Z=1;

#10


x++ ¦ ¦ y++&&z++
编译器是这样处理表达式:用stack来存放运算符,当遇见优先级低于栈顶的运算符则出栈进行计算,两个加号进栈了,遇见了¦ ¦,则会将+ +弹出栈进行计算,并且若是为1可以直接转到下一个语句,若为0仍得判断表达式后半部分。这个就是编译原理的知识,编译器总希望更高效率进行编译的!!!!!!

#11


很明显,因为 || 运算符只要左边的表达式为true,后面的表达式就不会计算了!

所以执行X++之后,y++&&z++不会执行,x变为2, y z仍然为1

#12


该回复于2008-08-07 09:18:03被版主删除

#13


写代码尽量不要搞优先级问题,多+括号看起来也舒服

#14


()这样不为难自己也不为难别人
你好大家都好

#15


优先级体现在算到右边的时候把y++当作右侧还是把y++ && z++当作右侧,先计算左侧这一点是不受优先级影响的。

#16


引用楼主 koknine 的帖子:
#include "stdio.h" 
main() 

    int x,y,z; 
    x=y=z=1; 
    if(x++ ¦ ¦y++&&z++) 
        printf("\n%d,%d,%d\n",x,y,z); 

这个程序在运行的结果是2,1,1。 
可是按照书上说的&&的优先级高于 ¦ ¦, 
那样应该先 算y和z啊,如果为真应该发生短路,不算x,这样结果应该是1,2,2。 
请问这是什么 原因,我理解的错误是什么地方啊


对嘛!

if里面,从左到右,先看||前面的,是1,那么后面的就不会计算了!也就是不理会后面的y++ z++

所以输出是那么样子!

#17


这时编译器优化的问题。
++运算容易产生二义性。慎用!

#18


x++ ¦ ¦y++&&z++ 等价于x++ ¦ ¦(y++&&z++)
先计算 x++,x=2为真,(y++&&z++)就不在计算,所以y和z还是为1

#19


引用 15 楼 Maxwell 的回复:
优先级体现在算到右边的时候把y++当作右侧还是把y++ && z++当作右侧,先计算左侧这一点是不受优先级影响的。

#20


编译器可能优化了

可以用括号解决这样的问题

#21


我也看书上的习题,才发现的,,搞了半天不明白。

#22


引用 8 楼 moonwrong 的回复:
引用 7 楼 Inhibitory 的回复:
楼主, 这种问题最好的解决办法是多用括号, 因为这种问题如果去死记硬背并不是一个好方法, 当有不确定的时候, 就用括号. 
而且即使你现在背下来了, 但是过一段时间也会很容易忘记, 优先级, 记住个大概就行了, 括号, 才是王道. 
 
up, 
x++¦¦y++&&z++ 
这样真的很麻烦,貌似在戏耍看代码的


我也是初学,做习题上机时候发现的

#23


引用楼主 koknine 的帖子:
#include "stdio.h" 
main() 

    int x,y,z; 
    x=y=z=1; 
    if(x++ ¦ ¦y++&&z++) 
        printf("\n%d,%d,%d\n",x,y,z); 

这个程序在运行的结果是2,1,1。 
可是按照书上说的&&的优先级高于 ¦ ¦, 
那样应该先 算y和z啊,如果为真应该发生短路,不算x,这样结果应该是1,2,2。 
请问这是什么 原因,我理解的错误是什么地方啊


应该是编译器优化了,即你的x++为true是||后面的值就不运算了。

#24


引用 9 楼 fansyong 的回复:
我来解释, ¦ ¦逻辑或 左右两边只要有一边为真的话,就成立. 
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++ 
所以,Y=1.Z=1;



原来是这样

#25


引用 9 楼 fansyong 的回复:
我来解释,||逻辑或 左右两边只要有一边为真的话,就成立.
先来看下左边X++X为1自加后为2.是真,于是,右边就不用判断了.也就是说不在执行Y++,Z++
所以,Y=1.Z=1;

说的很好

#26


isNaN(dd.value)

#27


以后再写这样的程序不加括号的一律重写

#28


引用 23 楼 hjessica 的回复:
引用楼主 koknine 的帖子:
#include "stdio.h"
main()
{
int x,y,z;
x=y=z=1;
if(x++ ¦ ¦y++&&z++)
printf("\n%d,%d,%d\n",x,y,z);
}
这个程序在运行的结果是2,1,1。
可是按照书上说的&&的优先级高于 ¦ ¦,
那样应该先 算y和z啊,如果为……