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
.