注册 登录
编程论坛 C++教室

一个逻辑表达式的问题

黄昏黄昏 发布于 2013-03-01 13:04, 544 次点击
int x, y, z;
 x=y=z=0;
 ++x||++y&&++z;
 cout<<x<<","<<y<<","<<z<<endl;
输出结果是1,0,0,  第三行语句的表达式的值为真。可是逻辑操作符的优先顺序不是! && || 吗?这样的话先++y,值为真,然后++z,也为真,那么++y&&++z就是真,然后再和(++x)进行||运算,但是为什么最终的y和z的值都是0呢?    另外,这个问题不是x++*x++……那种讨论因为不同编译器而定义不同行为的问题,我想知道++x||++y&&++z表达式的运算过程
8 回复
#2
fanpengpeng2013-03-01 13:24
“优先顺序” 这个提法不太准确 你错误的理解了 优先级 和 求值顺序 这两个概念
优先级不规定求值顺序
优先级只规定操作数与操作符的结合关系 即规定哪个操作数属于哪个操作符 比如本例中 根据优先级 只能得出以下结论 ++x || (++y && ++z);
但是其求值的顺序不是由操作符的优先级规定的 C语言中规定了求值顺序的4个操作符 && || ?: ,
根据 || 的求值顺序 其是先算左操作数 在左操作数为假的情况下 再计算右操作数 这里 ++x 为真 所以 后面的就不算了 结果为 1 0 0 也就是自然的了
其实这是C语言中一个很容易误解的地方 我前不久还在这儿犯过错误呢 所以这儿跟你分享一点经验
关于类似这些问题 《C陷阱与缺陷》 这本书里说了不少 推荐你有机会看看
#3
黄昏黄昏2013-03-01 13:53
回复 2楼 fanpengpeng
既然 求值顺序的4个操作符 && || ?:   那也应该是&&先啊,为什么到最后反而y和z都是0呢,而且,你写++x||(++y&&++z)  这样加括号的话就应该是++y&&++z进行运算,而你后面的解释意思是||的左操作数 ++x 为真,所以不进行后面的运算,相当于认为++x参与运算,这样不就和前面的两个说法矛盾了吗?不明白啊
#4
Susake2013-03-01 13:58
有妹子
#5
Susake2013-03-01 14:06
首先是从左往右的。
++x||++y&&++z
第一步:
(++x)      ||         (++y&&++z);
因为||这个符号的优先级最低。
第二步:
++x; 执行完之后x=1;
(对于||这个符号有个特点就是如果左边是非零,那么直接就返回值了,不用执行右边了。因为没有意义,1或0还是1.)
第三部:
||左边是非零,直接结束
x=1;y和z没变。
#6
fanpengpeng2013-03-01 14:38
回复 3楼 黄昏黄昏
c语言只规定了 && || ?: , 这四个操作符的求值顺序 不是说 这个四个操作符之间有先后关系 而是说每个操作符他的操作数之间的求值有明确的先后关系 而其他操作符是没有的
&& || 两个操作符都是先计算左边 然后对于右边符号短路求值原则
?: 条件运算符 先计算?前的操作数 然后对:前后的两个操作选择计算
, 逗号运算符 从左至右依次计算 取最后一个表达式的值
而这四个运算符之间没有先后关系 也不可能有先后关系
( ) 也是运算符 与其他运算符也只有优先级的区别 没有求值顺序的规定 正确理解了这个概念 你就不应该会认为 ++x || (++y && ++z) 应该先计算( )中的了
问题需要认真的去理解 如果现在接受有难度 需要多读书 会越来越明白的
#7
fanpengpeng2013-03-01 14:52
上面说了这么多 最重要的就是一句话 优先级不规定求值顺序
就是为了让你 不要把 运算符的优先级 和 先算后算 搅在一起 可能有些C语言的教材上表述优先级概念的时候 用的就是先计算后计算这样的话
导致严重的误导 你需要读更多的书去弄清更多本质的问题 这样才能尽可能的减少别人带来的误导
#8
黄昏黄昏2013-03-01 16:31
回复 6楼 fanpengpeng
明白了。。一个月没碰c都给忘了。。谢谢各位回答
#9
黄昏黄昏2013-03-01 16:31
回复 5楼 Susake
谢谢解释!!!!!!
1