I want to ask a question about the code below.
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
Why does the code prints "21 2 1" rather than "1 2 0" ?
Thanks for your help.
I want to ask a question about the code below.
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
Why does the code prints "21 2 1" rather than "1 2 0" ?
Thanks for your help.
Since the or is evaluated to true immediately in (a||c--), the c-- is never evaluated. The compiler does this. If a statement is true right off the bat, it won't bother evaluating the rest. So, c is never decremented as the right side of the or is never evaluated.
You can imagine this if statement
if((a||c--)&&(c&&b--)) printf("%d",b);
the following way
if ( a )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
else if ( c-- )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
So if the expression in the first if statement
if ( a )
evaluates to the logical true then this if statement
else if ( c-- )
never gets the control.
From the C Standard (6.5.14 Logical OR operator)
4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
Both || and && force left-to-right evaluation - the LHS is evaluated first and all side effects applied, then based on the result the RHS is evaluated.
Both operators short-circuit:
a || b, if a is non-zero, then the result of the expression is 1 regardless of the value of b, so b is not evaluated;a && b, if a is zero, then the result of the expression is 0 regardless of the value of b, so b is not evaluated.&& has higher precedence than ||, so a || b && c is parsed as a || (b && c).
Putting all that together, (a||c--)&&(c&&b--) is evaluated as follows:
a || c-- is evaluated as follows:
a is evaluated - its result is 1, so
c-- is not evaluated; because of this c's value is not changed, and
1
c && b-- is evaluated as follows:
c is evaluated - its result is 1, so
b-- is evaluated - its result is 3; as a side effect b is decremented, and
1
a || c-- and c && b-- evaluate to 1
The values of a and c are unchanged (1 and 1, respectively), while b has been decremented and its value is now 2.