x = y = z = 1;
z = ++x||++y&&++z;运算符的优先顺序如下--
(pre-increment) > && > ||所以答案应该是--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1但是,答案是2,1,1。
发布于 2013-08-02 02:04:39
使用逻辑运算符&&和||的表达式从左到右计算:
C99,第6.5.14-4节与按位
|运算符不同,||运算符保证从左到右的计算;在计算第一个操作数之后有一个序列点。如果第一个操作数比较不等于0,则不计算第二个操作数。
由于x++不是零,表达式短路评估的一切都向右||,包括它们的副作用。这就是为什么只有x++被计算,所以x变成了2。剩下的变量留在1中,就像它们应该做的那样。
发布于 2013-08-02 02:07:04
优先级与评估顺序不一样。优先级只是确定什么操作数和操作符应该放在一起。计算的确切顺序是未指定的,但逻辑运算符的除外,逻辑运算符按严格的从左到右的顺序进行计算,以启用短路。
因此,由于&&具有更高的优先级,因此首先将变量分组如下:
(++x) || (++y && ++z)然后,按照从左到右的顺序,计算++x .假设++x是真的,那么整个表达式都是真的。因此,表达式评估是短路的。(++y && ++z)从未被评估过。因此,y和z永远不会增加。
发布于 2013-08-02 02:02:53
表达式中没有序列点:
z = ++x || ++y && ++z;z的预增量与分配给z之间的关系。
因此,如果对++z进行了实际评估,这将使您立即进入未定义的行为领域,任何事情都可能发生。不允许在没有中间序列点的情况下修改同一对象两次。附件C(来自C99)列出了所有的序列点,这里的控制点遵循一个完整的表达式(整个计算和赋值)。
6.5 Expressions /2声明:
在前一个序列点和下一个序列点之间,对象最多应该通过表达式的计算修改其存储值一次。此外,应只读取先验值以确定要存储的值。
但是,假定x的初始值为1,在这种情况下,表达式的++z部分不会被计算。这并不会降低表达式本身的危险性,因为在起点为x == -1和y != -1的情况下,它将调用UB。
在这种情况下,标准的控制部分是6.5.14 Logical OR operator /4。
与按位操作数不同的是,保证从左到右的求值;在计算第一个操作数之后有一个序列点。如果第一个操作数比较等于0,则不计算第二个操作数。
因此,首先计算++x,因为它的计算值不是-零,所以从不计算++y && ++z .x增加到2,z被设置为该值的“真实性”,或者1,y在1中保持不变。
https://stackoverflow.com/questions/18007550
复制相似问题