Why the loop stops when i = -1?
for (i = len; i--;)
Full code is here http://rosettacode.org/wiki/Longest_increasing_subsequence#C .
Thx!!
The loop stops when the value of i-- is 0. Since i-- returns the value before the decrement, when i-- is 0, i is -1.
I don't see an answer worthy of being right, though Joachim Isaksson's comment is a concise explanation.
The loop stops when it evaluates a value of 0 or false.
The i-- is what's throwing you off. That's "post-decrement", i.e. the operator returns the current value of i (in this case, for the loop to evaluate), and immediately thereafter, decrements the current value. Pseudocode for postdecrement follows:
int retval = i;
i = i - 1;
return retval;
(Based on Eric Lippert's comments, technically, the compiler could do postdecrement as i = i - 1; return i + 1;. The point is that the value emitted by the operator is no longer the value of i.)
(as opposed to predecrement, which in pseudocode is simply):
i = i - 1;
return i;
So when the loop is evaluating i, it sees 0 so exits, but immediately after evaluating the operator has decremented i to -1.
So, to answer your question:
The loop doesn't stop when i = -1. It stops when i = 0, but then i is decremented to -1.
Your loop stops when the expression i-- becomes 0 because any non-zero value in C is treated as true and a zero as false.
At each iteration i is checked for true or false and then decremented .
for (i = len; i--;)
here i-- is the exit condition. when i-- is false which is 0 the loop will exit.
since i-- is post decreament i value is used for condition checking. so when
i=0;
loop exits after that i=i-1 is executed as part of post decrement so
i=-1;
when loop exits since first i's value is used after that it is decremented
FOR loops are composed of 3 parts:
for ( [Initialization] ; [Exit Condition] ; [Cycle Update] )
[Initialization] is used to assign a value to the loop index before the first iteration
[Exit Condition] is a boolean expression evaluated before each iteration. If it is true another iteration is executed, otherwise the FOR loop ends
[Cycle Update] is the instruction used to update the loop index at each iteration
a classical FOR statement looks like this:
FOR(I = len ; I > END_VALUE ; I--)
What is probably missing in your code is the exit condition, so the cycle update part is interpreted as an exit condition and consequently treated as a boolean expression. When the integer becomes 0 its interpreted boolean value corresponds to FALSE and the loop is ended. Any non-zero value is instead interpreted as a TRUE boolean and allows the execution of another iteration.
When a boolean value is needed, 0 is same as false. Anything other than 0 is true. So, it must stop when i is 0, not -1. You are seeing the value of i to be -1 because of the post-decrement operator.
Related
I think it would be an infinite loop because the value of i is decremented. but the loop stops when it returns 1. why?
int i ;
for (i = 5; i; i--){
printf("%d\n",i);
}
return 0;
}
In C, any nonzero integer or non-null pointer used in a conditional evaluates to true, and any zero value or null pointer evaluates to false. So, for example:
if (5) {
printf("This always executes.\n");
}
if (0) {
printf("You will never see this.\n");
}
In your case, the loop is
for (i = 5; i; i--) {
/* ... */
}
The loop condition is i, which means "loop while i is not zero, and stop once i becomes zero." As a result, once i drops to zero, the loop stops running. That means the last time you'll see the loop run is when i = 1, since after that it drops to zero.
Note the for loop syntax
for (initializationStatement; testExpression; updateStatement)
{
// statements inside the body of loop
}
The second part is a testExpression. You testExpression is to test whether i is true(non-zero) or false(zero.)
After 1 is printed (i==1) and the loop back to the start point with updateStatement (i--) , i is set to 0. Your testExpression is 0 which is viewed as false. So the loop exists immediately. ( 0 will not be printed either.)
If you want your codes to be an loop to print i infinitely, you can leave the testExpression empty.
There are 3 parts to a for loop:
The initialisation (executed before the first iteration of the loop), in your example i = 5
The condition (executed before each iteration of the loop), in your example i
The final expression (executed after each iteration of the loop), in your example i--
In most for loops you'll find that the condition is a comparison, e.g. i > 0, however in your example the condition is a value of 0.
In most languages 0 is considered as false, so it would stop the execution of the for loop once it reaches that number.
#include <stdio.h>
int main()
{
int i=0;
while(i++,i<=8);
printf("%d\n",i);
return 0;
}
Why is the increment of i done after the comparison in each test case?
i <= 8 succeeds for the last time when i = 8.
In the last iteration, i++ is executed, then i <= 8 fails because i = 9.
Note that the , is a sequence point, so i++ is absolutely guaranteed to be executed before i <= 8. Not so for similar constructs.
It's not. Your loop condition is i <= 8, it is first non-true when i reaches 9 (you're incrementing i by 1 each time, so it will be exactly 9). That is why it prints 9.
To reach to the print() statement, while loop must end. The terminating condition, controlling expression should evaluate to false (or, in other words, until the controlling expression compares equal to 0), i.e., it will be false only when i <= 8; evaluates to false. For a value of i as 9, that happens.
Next line, the value of i, gets printed. So, you see 9.
Increment of i is not done after the comparison in each test case. i++ is executed first and after that the comparison is done.
This is because when expressions are separated using commas in C, the expressions are evaluated from left to right and the value of the last expression becomes the value of the total comma separated expression.
So the value of
i++,i<=8
is actually the value of i<=8 and that comparison is done only after i++ is executed.
So the while loop here
int i=0;
while(i++,i<=8);
is equivalent to
for(i=1; i<=8; i++);
Hence the control exits the loop only when i is greater than 8. Since i is incremented by 1 on each iteration, this means that the loop is over when i becomes 9.
You started i = 0 and using while ( i++, i<=8 ) loop you incremented it's value until 8 and when it's increased one more time i = 9 , then loop condition became false and breaks the loop with i = 9. And that's why now, when you print i's value, it gave you 9.
How this for loop is working
int main(){
char i=0;
for(i<=5 && i>=-1; ++i ;i>0)
printf("%d \n",i);
printf("\n");
return 0;
}
Ahh thanks for the clarification.
Your asking why the for loop in your example is executing, even though the increment operand and loop condition have been swapped, and the fact that the variable is a char. Lets consider the proper structure of a for loop:
for (initialise variable; for condition; increment variable)
{
//Do stuff
}
The answer to your question is simple:
Your condition increases i by 1, but as you have pointed out, i is a char. Using operands on a char can convert it to another type, including int (refer C comparison char and int)
A loop will continue until its condition == false.
Your loop will continue running until i=0, which means it will continue to increase by 1 until it reaches 128, at which point it will overflow to -128 and continue to increase until it reaches 0 again.
Lets name parts of the for loop:
for( Expr1; Expr2; Expr3 )
DoStuff;
This is how a for loop works:
1. It executes Expr1 first. in your loop does nothing in fact, since it doesn't check the result of this execution.
Then it executes Expr2 and treat it's result as a condition if it's 0 terminates the loop, if it's "not 0" go to step 3. In your loop this means that i will be incremented, thus it's now 1, so result is true.
Then it runs the DoStuff part, in your case print out i value
Next it executes Expr3, no check, just run it, in your case does nothing again, since it's a condition and its result isn't used.
Next it goes back to Expr2 executes it and check it's result. now i is 2, still a true condition.
Again execute the DoStuff part and go to step 4
The loop will stop once i value changes back to 0.
When? since it's type is char, after reaching 127 it will overflow to -128 and then increment back to -1 and then 0. and stop.
Whenever you want to understand for loop in this kind of situation you can convert for loop into while to understand it.
The for syntax is:
for (initialization; condition; operation)
...
It can be converted into while as:
initialization;
while (condition) {
...
operation;
}
So in your case
i <= 5 && i >= -1; // Initialization
while(++i) { //condition
printf("%d \n", i);
i > 0; // operation
}
Initialization part will be execute once it will check for condition.Here in your case it is ++i so increment every time.Here i>0 means if i==0 then loop will stop it does not matter i is positive or negative Thumb rule to remember in this kind of situation is if (i == 0 ) then true else false. i>0 remains true)in every case after that so loop is infinite.
To understand for loop best answer I have seen in SO is this
There's not rule about the order of for loop condition and increment operation, the latter even don't need to be an increment operation. What it's expected to do is determined by you. The code is just same as the following semantically.
char i = 0;
i <= 5 && i >= -1; // Run before the loop and only once. No real effect here.
while (++i) { // Condition used to determine the loop should continue or break
printf("%d \n", i);
i > 0; // Run every time inside the loop. No real effect here.
}
BTW: It'll be an infinite loop (because ++i is a nonzero value until overflow).
Sry I'm new to C language.
Can someone help me understand what happens in the "for" loop:
When I run this code I get nothing, it's not even entering the loop:
for( count=0 ;count--;count--)
{
printf("\n%5d", count);
}
And when I run this code I get infinite entrances to the loop:
for( count=1 ;count--;count--)
{
printf("\n%5d", count);
}
And when I run this code I get 1 entrance to the loop:
for( count=2 ;count--;count--)
{
printf("\n%5d", count);
}
And so on for every count=odd number I get infinite entrances, and for every count=even number I get a limited number of entrances
Can someone explain me why is this hapening?
for(left;middle;right) The middle expression is the condition - an expression which is contextually convertible to bool. This expression is evaluated before each iteration, and if it yields false (or 0 in the case of an int), the loop is exited.
foo-- is a post-operator, which means the value is foo is evaluated first and then it is decremented.
Putting these two together,
Case1: Before entering the loop, count-- is evaluated. Count current value is 0. So loop is not executed.
Case2: count-- evaluates to 1, loop is entered once. count-- is executed at the end of the loop. count-- now evaluates to -1 at the beginning of the loop, so loop is executed again, and so on - ad infinitum
Case3: count-- is 2, end of the loop count-- is 0, so loop exits after 1 iteration.
I think you first need to to know exactly what count-- is. This means that first count will be evaluated as part of the condition, then decremented. This means that count-- is 0 in this case, making the for loop condition evaluate to 0. After the condition is evaluated, count is -1, but this doesn't matter because count was 0 during the condition check so the loop never runs.
for(count = 0;count--;count--)
{
printf("\n%5d", count);
}
The next loop starts count at 1, which means count-- will be evaluated to 1, this makes the condition check of the for loop equal to 1. After the evaluation, count becomes 0. This means the for loop will enter and print out the message. When the code block ends, the statement count-- gets executed, setting count to -1. Then we do the check again. We see that count-- evaluates to -1 so we will loop again. After the evaluation, count will be set to -2 and we will enter the for loop again. This function runs forever because count will always be odd when we get to the for loop check, therefore count can never be 0 and we never break from the loop.
for(count = 1;count--;count--)
{
printf("\n%5d", count);
}
You should now be able to figure out why the last one only runs once:
for( count=2 ;count--;count--)
{
printf("\n%5d", count);
}
Obviously after the first evalution, count gets decremented. Then once the code block gets executed, it is decremented again. Therefore when we get to the conditional check in the for loop, count is 0 and we break.
can anyone explain the working of the for loop in the following code:
#include<stdio.h>
#include<conio.h>
int main()
{
char i=0;
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
getch();
}
Let's break the for statement down, we have three phases, the initialiser, the test, and the modifier:
for(<Initialiser>; <Test>; <Modifier>)
<content>;
In your case:
for(i<=5&&i>=-1;++i;i>0)
// initialiser: i<=5&&i>=-1;
// test: ++i;
// modifier: i>0
The initialiser is done first. Here no assignment is done. Two boolean expressions (denoted by the >= and <= operators are compared in a logical &&. The whole initialiser returns a boolean value but it doesn't do anything. It could be left as a blank ; and there would be no change.
The test uses the pre-increment operator and so returns the result of i+1. If this result is ever 0 it evaluates as false and the loop will terminate. For any non-zero value it evaluates to true and continues. This is often used when i is initialised to a value less than zero and so the test will increment i until i+1 results in a zero, at which point the loop terminates.
Finally we have the modifier, which in this case simply uses the > operator to evaluate to a boolean value. No assignment is done here either.
The fact is that you've gotten the test and the modifier confused and put them in the wrong positions but before we sort that out let's see how it would work…
We begin with:
char i = 0;
…and for all intents and purposes this does the same thing as our for loops initialiser would do in normal circumstances. The next thing to be evaluated is the for loop's initialiser:
i<=5 && i>=-1;
Because i is 0 it is less-than-or-equal-to 5 and it is greater-than-or-equal-to -1. This expression evaluates to 1 but nothing is done with that value. All we've done is waste a bit of time with an evaluation.
Next up is the modifier to test whether or not the for loop's inner block should be executed:
++i;
This evaluates to 1 and also assigns that value to i. Now, as it's evaluated to a non-zero number, the loop executes:
printf("%d\n",i);
And the digit 1 is printed to the screen... Now it's the modifier that gets executed:
i>0
Well, i is 1 so that is greater-than 0. This evaluates to 1 (or true). Either way, this is ignored. The purpose of the modifier isn't to test or check anything. It's there so that you can change the state of the program each time the for loop iterates. Either way, the loop repeats and it will do this for a very long time. Why? Because ++i is going to evaluate to a non-zero number for a while. Whether or not it will ever terminate depends on how your system deals with integer overflows.
This is what you meant to do:
#include<stdio.h>
#include<conio.h>
int main()
{
for(char i=0; i<=5&&i>=-1; ++i)
printf("%d\n",i);
}
Do you see the difference? Our initialiser now starts the loop with the state of i as zero. We then test if it's within the bounds of -1 to 5 and each time we iterate we increment i by 1. This loop will output:
0
1
2
3
4
5
This snippet:
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
Does the same as this:
i<=5 && i>=-1; //statement with no effect
while(++i)
{
printf("%d\n",i);
i>0; //statement with no effect
}
So, it's going to print i until ++i evaluates to 0. This will happen after i overflows and becomes negative, then incrementing towards 0. That will take 255 iterations to happen, since chars can store up to 256 different values.
for ( variable initialization; condition; variable update ) {
}
the variable initialization phase is done only once when the for loop starts.
the condition is checked everytime before running code inside the loop. if the condition is false then the loop is exited.
the variable update is done after the first iteration, from the second iteration it is done before the condition check.