main()
{
int k = 5;
if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement
print f("%d",k);
}
// Here answer is 7 but why ?
main()
{
int k = 5;
if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement
print f("%d",k);
}
// Here answer is 7 but why ?
++k < 5
evaluates to false (6 < 5 = false), so the RHS of the &&
operator is not evaluated (as the result is already known to be false). ++k <= 8
is then evaluated (7 <= 8 = true), so the result of the complete expression is true, and k
has been incremented twice, making its final value 7.
Note that &&
and ||
are short circuit boolean operators - if the result of the expression can be determined by the left hand argument then the right hand argument is not evaluated.
Note also that, unlike most operators, short circuit operators define sequence points within an expression, which makes it legitimate in the example above to modify k
more than once in the same expression (in general this is not permitted without intervening sequence points and results in Undefined Behaviour).
Unlike many questions like this, it appears to me that your code actually has defined behavior.
Both &&
and ||
impose sequence points. More specifically, they first evaluate their left operand. Then there's a sequence point1. Then (if and only if necessary to determine the result) they evaluate their right operand.
It's probably also worth mentioning that due to the relative precedence of &&
and ||
, the expression: if(++k <5 && k++/5 || ++k<=8)
is equivalent to: if((++k <5 && k++/5) || ++k<=8)
.
So, let's take things one step at a time:
int k = 5;
if(++k <5 &&
So, first it evaluates this much. This increments k
, so its value becomes 6. Then it compares to see if that's less than 5, which obviously produces false.
k++/5
Since the previous result was false
, this operand is not evaluated (because false && <anything>
still always produces false
as the result).
|| ++k<=8);
So, when execution gets to here, it has false || <something>
. Since the result of false | x
is x
, it needs to evaluate the right operand to get the correct result. Therefore, it evaluates ++k
again, so k
is incremented to 7. It then compares the result to 8, and finds that (obviously) 7 is less than or equal to 8 -- therefore, the null statement following the if
is executed (though, being a null statement, it does nothing).
So, after the if
statement, k
has been incremented twice, so it's 7
.
In following:
for &&
"something" is evaluated when first condition is True
for ||
"something" is evaluated when first condition is False
( (++k <5) && (k++/5) ) || (++k<=8)
( 6 < 5 AND something ) OR something
( False AND something ) OR something
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
False OR 7 < 8
False OR True
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
True
So k
comes out to be 7
Initially k
is assigned 5
, in your declaration, then in following if condition:
++k < 5 && k++ / 5 || ++k <= 8
// ^
// evaluates
Increments k
to 6 then its and LHS of &&
operand evaluates false.
6 < 5 && k++ / 5 || ++k <= 8
// ^ ^^^^^^^
// 0 not evaluates
Then because of Short-Circuit behavior of && operator k++ / 5
will not evaluates.
Short-Circuit behavior of && operator is:
0 && any_expression == 0
, so any_expression
not need to evaluate.
So above step 2 conditional expression becomes:
0 || ++k <= 8
// ^^^^^^^^
// evaluates
Increments k
to 7 then its:
0 || 7 <= 8
because you have ;
after if
, so no matter whether if condition will evaluates True or False printf()
will be called with k = 7
.