I really have a hard time understanding how the following piece of code works:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
output: -5, -8, -11, -12
I mean I get what
while ( --x > -10)
output: -3, -4, -5, -6, -7, -8, -9, -10
and
while (x -= 2)
output: -> infinte loop
alone would do, but how do they work with the and operator? I mean for "while (x -= 2)" the condition is only met when x = 2, so how can the while loop even end and not go infinite like it does when only "while (x -= 2)" is used?
CodePudding user response:
The fact that you start with -5 is quite obvious:
int x = -2;
while ( --x > -10 && (x -= 2)) {
--x turns x from -2 into -3.
x -= 2 turns x from -3 into -5.
... and so it goes further: using --x and x -= 2 you decrement again by 3, so you get values like -8 and -11. (When you reach -11, you already checked for "> -10", which was -9 at that moment)
Then, again you do --x, turning -11 into -12, but you jump out of the while loop and you print that new value again.
Edit, more clarification:
x -= 2 means x=x - 2, it's not some kind of a check.
CodePudding user response:
The test is purposely obfuscated. Here are the steps:
--x > -10always decrementsxand compares the resulting value to-10, breaking from the loop ifxreaches -10 or below.- if
x >= -10from the previous test,(x -= 2)further decreases the value ofxby 2 and tests whether the resulting value is non zero. The only value ofxfor which(x -= 2)is zero isx = 2. In the present case,xis always negative so this test is always true.
starting from x = -2, the iterations are:
--x->x = -3, the comparison is true
(x -= 2)->x = -5,printfoutputs-5--x->x = -6, the comparison is true
(x -= 2)->x = -8,printfoutputs-8--x->x = -9, the comparison is true
(x -= 2)->x = -11,printfoutputs-11--x->x = -12, the comparison is false, the loop is exitedthe final
printfoutputs-12
CodePudding user response:
Value of x Output
In the first loop:
x = -3, x = -5 -5
In the sec loop:
x = -6, x = -8 -8
In the third loop:
x = -9, x = -11 -11
In the fourth loop -> exits the while loop since x > -10:
x = -12, x = -14 -12
CodePudding user response:
This is some "obfuscate things just for the heck of it" algorithm, from which very little of value can be learnt, except "don't write crap like this".
What it does is to decrease the value by 3, but split that decrease in two steps. First always decrease by 1 and then by 2 more, unless it's the very last lap in the loop. So the && serves two purposes: to only decrease by 1 the last time of the iteration, as well as a sequence point to allow two modifications of x in the same expression (which is very bad practice, && or not).
For those not participating in the International Obfuscated C Code Contest, it might make more sense to rewrite the code similar to this:
int x;
for(x = -5; x >= -11; x -= 3)
{
printf("%d, ", x);
}
printf("%d", x 2);
This is also nonsense code but at least it is readable. As a bonus, it also contains less branching than the obfuscated version.
