Why is "if (i ++ && (i == 1))" false, where am I an int storing the value 1?

{ int i = 1; if (i++ && (i == 1)) printf("Yes\n"); else printf("No\n"); } 

According to my understanding, in if , the expression ( i==1 ) will be calculated first, which should return 1 , and then it is logically connected with 1 , which is the value i >, so the expression should return 1 && 1 == 1 , but else is executed.

Can someone explain why the else part is done?

+43
c if-statement logical-operators
Jul 12 '15 at 3:26
source share
5 answers

No. In C, there is a sequence point between the && operator LHS estimate and the RHS estimate, and the increment must be performed and performed before the RHS estimate. Thus, i++ is executed (equivalent to i++ != 0 ), and the increment is completed (and the expression evaluates to true), therefore, by the time RHS is evaluated, i == 2 and, therefore, the general expression is false, and you will get “No”. If the &HS of the && operator evaluates to false (0), the RHS will not be evaluated due to the "short circuit" property of the && operator.

Only a few operators have the property of having a sequence point between the LHS and RHS ratings: && , || and , (as an operator, and not as a separator in the argument list) - and there ? : ? : also, which is not a binary operator, but has a sequence point after evaluating the condition and before evaluating the expression after ? or the expression after : (from which one or the other, but not both, are always evaluated).

Operators && and || are the only operators with the "short circuit" property. RHS && is evaluated only if LHS is evaluated as true; RHS || evaluated only if the LHS evaluates to false.




Point refinement

Iwillnotexist Idonotexist correctly approved :

The C11 standard did not do away with sequence points, only the C ++ 11 standard did.

C ++ 11 (ISO / IEC 14882: 2011) states:

1.9 Program Execution

¶13. The previously segmented segment is an asymmetric, transitive, pairwise relation between estimates made by one (1.10), which causes a partial order among these estimates. For any two evaluations, A and B, if A is sequenced to B, then the execution of A must precede the execution of B. If A is not sequenced to B and B is not sequenced to A, then A and B are not affected. [Note: Performing non-overlapping scores may overlap. -end note] Scores A and B are indefinitely sequenced when either A is sequenced before B or B is sequenced to A, but that is not indicated. [Note: vaguely sequenced estimates cannot overlap, but either can be performed first. -end note]

The term “sequence point” does not appear at all in C ++ 11 (the only match is “sequence pointer”).

C11 (ISO / IEC 9899: 2011) states:

5.1.2.3 program execution

¶3. The previously segmented segment is an asymmetric, transitive, pairwise relation between estimates performed by a single thread, which causes a partial order among these estimates. For any two evaluations, A and B, if A is sequenced before B, then the execution of A precedes the execution of B. (Conversely, if A is sequenced to B, then B is the sequence after A.) If A is not sequenced before or after B, then A and B are unsequenced. Scores A and B are indefinitely sequenced when A is sequenced either before or after B, but that is not indicated. 13) . The presence of a sequence point between the evaluation of expressions A and B implies that each calculation of the value and the side effect associated with A are sequenced before each value and the side effect associated with B. (A brief description of the points in the sequence is given in Appendix C.)

13) Performing non-referential estimates can alternate. Uncertainly ordered estimates cannot be interleaved, but can be performed in any order.

So, C11 retains the points of the sequence, but adds the “previously sequenced” and related terms, using essentially the same terminology as C ++ 11.

+92
Jul 12 '15 at 3:30
source share

Here is a simple explanation

enter image description here

and why does this condition become "false"

+41
Jul 12 '15 at 18:42
source share

When && used in an expression, its arguments are guaranteed to evaluate from left to right . Thus, i will have a value of 2 in the evaluation (i==1) . Therefore, the expression is false, and the else part will be executed.

However, note the completeness that if the left argument evaluates to false or 0, then the correct argument is not evaluated at all.

+28
Jul 12 '15 at 3:36
source share

I think 1 & 1 = 1 and 1 & 0 = 0 are clear to you. Michael L. the answer seems good to me. But still, I'll try to figure it out a bit. Here is a link that provides a list of operator priorities:

http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm

If you follow this link and refer to this table, you will find out that && has left to the right associativity. So first I get 2 AFTER the left side (Sruit tried to show this diagram), and then for the right side I == 1 the check is done. We can verify this by writing code like the one below:

This code explains that i = 2 when the thread of execution reaches i == 1.

 #include <stdio.h> int main() { int i = 1; if (i++ && (printf("%d\n",i))) printf("Yes\n"); else printf("No\n"); return 0; } 

So the output is:

2

Yes

So 2 == 1 turns out to be false, and ultimately the answer is surprising! The right side bracket gives 0 and the left side 1, so 1 && 0 = 0. I think this is fair enough to understand.

+1
Jul 15 '15 at 19:40
source share

You are confused because in the loop operator i ++ is used to increment posts. eg.

 for (i=0;i<1;i++) 

In the above program, loop i will first get the initial value and the test condition. The if condition if true, so it increments i and evaluates i the old value for the loop body, but outside the loop body has a new value of 1 .

In your question, you use if , and the region of the old value i ends when it encounters a logical operator, automatically receives a new value and increases to 2 so that the condition returns false.

0
Jul 15 '15 at 15:28
source share



All Articles