The thing you need to focus on here first is the properties of prefix and postfix operators and their differences.
For Postfix increment and decrement operators, C11
, chapter §6.5.2.4, (emphasis mine)
The result of the postfix ++
operator is the value of the operand. As a side effect, the
value of the operand object is incremented [...] The postfix --
operator is analogous to the postfix ++
operator, except that the value of
the operand is decremented.
For Prefix increment and decrement operators, C11
, chapter §6.5.3.1, (emphasis mine)
The value of the operand of the prefix ++
operator is incremented. The result is the new
value of the operand after incrementation. [...] The prefix --
operator is analogous to the prefix ++
operator, except that the value of the
operand is decremented.
Now, there comes the property of the Logical AND (&&
) operator. From chapter §6.5.13, (again, emphasis mine)
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 equal to 0, the second
operand is not evaluated. [...]
So, in your case,
int a = 1, b = 1, c = -1;
c = --a && b++;
gets evaluated as
c = 0 && .....; // done..., a is decremented to 0,
// so, LHS of && is 0, RHS is not evaluated,
// b remains 1
// and finally, C gets 0.
On the other hand, if logical OR (||
) would have been used, then, as per the property, mentioned in chapter §6.5.14
[...] 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.
So, for the case
int a = 1, b = 1, c = -1;
c = --a || b++;
it will be evaluated as
c = 0 || 1; //yes, b's value will be used, and then incremented.
So,
printf("%d %d %d", a, b, c);
will be
0 2 1