2013-08-18 55 views
-5
main()  
{ 

    int k = 5; 

    if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement 
    print f("%d",k); 
} 

//这里的答案是7,但是为什么?如何编译if语句

+0

注意:短电路操作员是序列点。 –

+0

**阅读**:[在C编程语言中&&的行为](http://stackoverflow.com/questions/18229657/behaviour-of-in-c-programming-language/18229763#18229763) –

+0

如何声明是内部执行“if()” 如何:++ k <5 && k ++/5 || ++ k <= 8是否执行? –

回答

2

在以下几点:当第一个条件是真

|| “东西” 时,第一个条件是假

((++k <5)  &&   (k++/5))  ||  (++k<=8) 

(6 < 5   AND  something)  OR something 

(False   AND  something)  OR something 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
       False      OR 7 < 8 

       False      OR True 
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     
              True 

所以k

&& “东西” 被评为评估出来是7

+0

这可以使用更多的解释性文字。 –

+0

POW不错!再次一个艺术的答案,可读! –

6

++k < 5的计算结果为false(6 < 5 = false),因此&&运算符的RHS未被评估(因为结果已知是错误的)。然后++k <= 8进行评估(7 < = 8 =真),所以完整的表达式的结果为真,和k已递增两次,使得其最终值7.

注意&&||short circuit布尔操作符 - 如果表达式的结果可以由左手参数确定,那么不评估右手参数。还请注意,与大多数操作员不同,短路操作员在表达式中定义了sequence points,这使得在上例中合法地在同一个表达式中多次修改k(通常,在没有插入序列点的情况下这是不允许的结果在Undefined Behaviour)。

1

最初k分配5,在你的宣言,然后在if条件如下:

增量k至6那么它和&&操作的LHS判断为假。

6 < 5 && k++/5 || ++k <= 8  
//^ ^^^^^^^ 
// 0 not evaluates 

然后因为Short-Circuit behavior & &运营商的k++/5不会评析。 & &运营商的

短路行为是:
0 && any_expression == 0,所以any_expression并不需要评估。

所以上面的步骤2的条件表达式变为:

0 || ++k <= 8  
// ^^^^^^^^ 
// evaluates 

增量k到7,然后它的:

0 || 7 <= 8  

,因为你有;if,所以无论是否条件将判断为真或假printf()将被调用k = 7

4

与许多像这样的问题不同,在我看来,你的代码实际上已经定义了行为。

&&||均施加顺序点。更具体地说,他们首先评估它们的左操作数。然后有一个序列点。然后(当且仅当需要确定结果时),他们评估他们的右操作数。

它可能还值得一提的是由于&&||,表达的相对优先级:if(++k <5 && k++/5 || ++k<=8)相当于:if((++k <5 && k++/5) || ++k<=8)

那么,让我们拿东西,在一步一个脚印:

int k = 5; 

if(++k <5 && 

因此,首先它的计算结果这么多。这增加了k,所以它的值变为6.然后比较看看它是否小于5,这显然产生错误。

k++/5 

由于先前的结果是false,该操作数是评价(因为false && <anything>仍总是产生false作为结果)。

|| ++k<=8); 

所以,当执行到这里时,它有false || <something>。由于false | x的结果是x,因此需要评估右操作数才能获得正确的结果。因此,它再次评估++k,因此k增加到7.然后它将结果与8进行比较,并且发现(显然)7小于或等于8 - 因此,在执行if之后的空语句是执行(尽管是空语句,它什么都不做)。

因此,if声明后,k已经增加了两次,所以它的7。 “如果第二表达式,每一个值计算和副作用相关联:


  1. 在C++ 11,短语“序列点”已替换像“之前测序”的短语,如第一个表达式在与第二个表达式关联的每个值计算和副作用之前都被排序。“最终,效果是相同的。