我想知道为什么这个代码会产生2

时间:2011-11-03 23:36:41

标签: c

我不知道是否有人能为我解释这段代码?

unsigned int x = 0;
(x ^= x ) || x++ || ++x || x++;

printf("%d\n", x);

当我使用gcc 4.2在我的计算机上编译它时,输出为2.

最初我认为这个行为可能未指定,但后来我想||将优先于其他运营商,所以答案不应该是3吗?由于有三个“++”。

有人可以解释一下吗?感谢

6 个答案:

答案 0 :(得分:6)

    评估
  • (x ^= x)并产生0,因此:
  • 评估
  • (x++)并且产生0 ,因此:
  • 评估
  • (++x)并产生2,因此停止

这一切归结为一条规则:||只评估其右侧是否为假。

答案 1 :(得分:5)

问题是||运营商正在短路。一旦找到真值,就不再需要检查剩余的||语句;答案已经为人所知。

(x ^= x)评估为0.
x++评估为0,然后将x增加到1 ++x评估为2 - 真。

不需要计算final或语句。它“短路”并立即返回true。

答案 2 :(得分:2)

行为定义明确。您正在观察||的短路行为;最终的x ++永远不会被评估。

答案 3 :(得分:1)

这就是行动中的短路语义。第一个表达式x ^= x的计算结果为0,第二个表达式的计算结果为0。第三个评估为2,然后逻辑表达式被短路,因为它的结果已经确定为true

答案 4 :(得分:0)

||运算符之间的表达式将从左到右进行评估,直到true为止:

(x ^= x ) 

x中的所有位设置为0 /关闭。 (false);

x++ 

增量x,现在为1,但仍为false,因为这是一个后期增量。

++x 

(pre-)增量x,现在为2,还有true,因此无需评估||的右侧。

答案 5 :(得分:0)

当然你不应该使用这样的结构,但让我们分析表达式。

有4个表达式与快捷方式相结合:

a || b || c || d

b,c和d仅进行评估,如果a为假,则c和d仅在b为假的情况下进行,而d仅在前者的所有内容均为假时才进行。

Ints被评估为0 == false,其他一切都不是假的。

x ^= 0 
x为0的

再次为0。

x++ 

被评估并随后增加,因此它的计算结果为0,调用表达式c,但后来x将增加。

++x 

首先递增,导致1,然后评估(导致1)这是原因,为什么d没有被评估,但是b的增量是未决的,所以我们得到2.

但是我不确定,这种行为是否已经完全定义并且会在所有编译器上产生相同的结果。

Avoid it.