Reputation: 189
I just wrote a little program to help me get familiar with logical expression in C, and I was expecting the result to be:
1
1 1 1
#include <stdio.h>
int main(void)
{
int I = 1, J = 1, K = 1;
printf("%d\n", ++I || ++J && ++K);
printf("%d %d %d", I, J ,K);
return 0;
}
Instead, I got:
1
2 1 1
The value of I
was incremented by 1, and I have no idea why.
As far I have learned, I
wasn't assigned(=
) any new value in my program, so how was it value be changed?
Upvotes: 2
Views: 147
Reputation: 15042
Your question addresses two separate issues.
The first one: Why is I
incremented?
The second one: If the output is 2 1 1
and I
was incremented why aren´t J
and K
incremented then too?
Why is
I
incremented?
++
is the increment operator. It increments an operand by 1
count, analogous to the expressions i = i + 1
or i += 1
, where i
stands for the operand.
There is a difference between set ++
in front of (++i
) or behind (i++
) an operand. The answers under the following linked question address the difference at its best, so I won´t go too much in detail about this topic here since the difference is not crucial important at your provided code and I just wanted to annotate that circumstance for that you use the increment operator in your future programs properly and avoid further confusions.
C: What is the difference between ++i and i++?
Back to your code.
Since you use:
printf("%d\n", ++I || ++J && ++K);
I
is immediately incremented by 1
inside the expression, so its value is actually 2
, although this does not influence the logical evaluation because any value which is non-zero would be evaluated as 1
/true
as result of a logical condition test.
That´s why
printf("%d %d %d", I, J ,K);
prints 2
as the value of I
.
Why aren´t
J
andK
incremented then too?
Logical testing evaluates from left to right. &&
has a higher precedence than ||
. &&
combined expressions/sub-conditions need to be fulfilled together to be evaluated as true
condition. As soon as a condition becomes true
, which is the case with ++I
, the evaluation of the remaining conditions is omitted since it is redundant.
That´s why J
and K
aren´t incremented by 1
with:
printf("%d\n", ++I || ++J && ++K);
but I
is.
Thus, the correct output of
printf("%d %d %d", I, J ,K);
is:
2 1 1
Upvotes: 5
Reputation: 23802
Looking at the expression
printf("%d\n", ++I || ++J && ++K);
++I || ++J && ++K
is a logical expression, yes, but it's also incrementing all you variables, so they all should be 2
in the end of the expression and your output should be:
1 // true expression, I, J and K are all positive values
2 2 2
So why does this not happen?
Well, since I = 1
, no more evaluations are needed, because the compiler knows that 1 || 0 && 0
is 1
, (note that the evaluation is left to right and &&
has precedence over ||
) this is the reason why ++J
and ++K
are not evaluated, and thus not incremented.
So, in the second printf
you will have I = 2
, J = 1
and K = 1
.
Upvotes: 2
Reputation: 123468
The expression ++I
evaluates the current value of I
plus 1
; as a side effect, I
is incremented.
Due to operator precedence rules, the expression ++I || ++J && ++K
is parsed as ++I || (++J && ++K)
. Both ||
and &&
force left-to-right evaluation, so ++I
is evaluated first.
Both ||
and &&
short-circuit - if the left-hand operand of ++I || ++J && ++K
(++I
) is non-zero, then the result of the expression is true (1
) regardless of the value of the right-hand operand (++J && ++K
), so the right hand operand isn’t evaluated at all.
If I
starts out as -1
, then ++I
would evaluate to 0
(false) and then ++J && ++K
would be evaluated. If the left-hand operand ++J
evaluates to 0
(false), then the result of the expression is false regardless of the result of ++K
, so ++K
won’t be evaluated.
Upvotes: 1