Does checking count-- in a for loop cancels the loop? - c

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.

Related

I did not understand why this for loop end with 1. why not 0 or -1 or something else

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.

Execution of for loop in C

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).

Understanding the basics of the for loop in C language

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.

For loop why the variable out of the loop is "last index" + step?

I was just wondering why this :
int i;
for (i=0; i<5; i++){
printf("%d\n",i)
}
printf("Here i get the result that misleads me : %d\n",i)
The last value is 5.
My logic is :
From 0 to 4 -> printf
If i > 4 (since we are dealing with integers) stop the loop.
But the loop stopped at 4 not 5 ! Why do I get 5 after the loop ? Why does it ever increment ?
Arbitrary ?
Thanks,
There are three clauses in the for statement.
The init-stmt statement is done before the loop is started, usually
to initialize an iteration variable.
The condition expression is tested before each time the loop is
done. The loop isn't executed if the boolean expression is false
(the same as the while loop).
The next-stmt statement is done after the body is executed. It
typically increments an iteration variable.
So, end of each for loop execution, increment operation executed, and, in the 4th iteration, value of i is 5 and the for loop was broke as the value is 5 in 5th iteration.
unroll what's happening
int i = 0;
while( i < 5 )
{
// body of for loop
i++;
}
// i == 5 here as i must be greater than or equal to 5 to break out of while loop
How does for loop works:
for (initialization; condition; increment-decrement)
Statement
Run initialization (i=0)
Check condition (i<5), if true then jump to 3 else jump to 5
Do statement ({ printf("%d\n",i) })
Do increment-decrement (i++), jump to 2
Exit loop
Before last iteration i == 4, then it prints 4, increments i. Therefore after last iteration i == 5, !(5 < 5), i.e. condition is false, exit from loop.
At the end of each iteration, the loop index is incremented. Then the program checks whether to run another loop. It finds "no the index is too big and fails the condition", so it doesn't execute and exits.
Until the index gets too big, the condition doesn't fail. It HAS to get too big (so the loop doesn't execute).
And that is why...
Because after the 4th loop:
i++ is performed, i becomes 5
i<5 is evaluated as false
Thus the loop exits
And then you get i==5 after the end of loop.
Indeed, after each loop, i++ is evaluated before checking for the exit condition, i<5.
for (int i = 0; i < 5; ++i) goes like this:
i <- 0
check whether i < 5, if yes, loop, otherwise stop
do the loop
i <- i + 1
goes to step 2
Let's see this loop:
for (i = 0; 0; i++)
do_smth();
You'll see that this loop doesn't execute at all. Because the condition is false even from the beginning.
Now
for (i = 0; i < 4; i++)
i++;
Clearly increases i twice for every run (once inside the loop and then because of the third part of the for). In the end, i will have the first even value which make the condition false. That is 6. Thus, there is no link between the step and the value of the variable outside the loop.

Condition in a 'for' loop

I am experimenting about what can be put into a for loop declaration in C and how it can be used. I tried the following:
#include <stdio.h>
int stupid(int a)
{
if(a == 3)
return 1;
else
return 3;
}
int main(void)
{
int i, j;
for(i=0; stupid(i)==3,i<10; i++)
printf("%d\n", i);
return 0;
}
When I run the program it just prints the number from 1 to 10, and if I use && instead of comma between the stupid(i)==3 and i<10, then the program just prints the numbers up to 3. Why?
I don't really understand how this works and I was expecting the loop to pass all numbers and "skip" 3, but continue up to 10 and that's not really happening. Why does this happen? Is there some site where this is more clearly explained?
The second clause in the for loop (in your case stupid(i)==3,i<10) is a conditional that is evaluated prior to each entry of the loop body. If it evaluates to true then the loop body is executed. If it evaluates to false then the loop ends and execution continues after the loop body.
With the comma (stupid(i)==3,i<10), the code evaluates stupid(i)==3, forgets the result, and then evaluates i<10, and uses that result for the loop condition. So you get the numbers from 0 to 9.
stupid(i)==3 && i<10 will evaluate to true only if both parts of the expression are true, so when i=3, stupid(i)==3 is false, and the loop exits.
The comma operator evaluates the part before the comma, discards the result, evaluates the part after the comma, and returns that. So in your for loop the part after the comma is i < 10 and this is what is returned as condition for the for loop. That is why it prints the numbers 1 to 10 if you have the comma operator in it.
If you put the && operator in it, it means that both conditions before and after the && have to be met. Otherwise the loop terminates. So if i == 3 the left part evaluates to false and your loop ends.
The comma operator evaluates both, but then overall returns the value of its second operand. Since stupid() doesn't have any side effects, that means nothing much of use really happens here and you're overall just checking to see if i<10.
When you change it to && then both functions must return true (non-zero) for the iteration to continue. On the first pass through, on which the statement evaluates to false, the for loop halts and control continues past it.
The for loop will only continue if the conditions are met. If you place an if statement within the for loop to verify that stupid(i) is equal to three, the for loop will continue.
Using the , operator expands to each line being run. The last line is expected to return a Boolean expression that indicates whether the next iteration should be executed.
In this case, while stupid() does get called, it only checks the return value from the expression i < 10 to decide further execution.
In the for loop, there are three expressions needed, and they are separated by semicolons.
The first is an initializer, and it is run one time before the loop starts. It usually initializes the loop variables.
The second is a condition, and it is run right after the initializer and then before each subsequent iteration. If it is true, the loop statements are run. If it is false, the loop is over.
The third is an expression that is run right after each iteration and right before the condition is checked before the next iteration. It usually progresses the loop by changing the loop variable.
Your condition stupid(i)==3,i<10 uses the comma operator. The comma operator runs each side, but it returns only the value of the right hand side. The value of stupid(i)==3 is completely ignored. The condition stupid(i)==3 && i<10 is true only if both sides are true.
Remember, when the condition is false, the loop is over -- the iteration is not just skipped, the entire loop is over. To get what you want, use
for(i=0; i < 10; ++i) {
if (stupid(i)==3) {
printf("%d\n",i);
}
}
This will go through 0-9, but skip the code if stupid(i) is not 3.
Use:
int main(void)
{
int i,j;
for(i=0; i<10; i++, i+=i == 3)
printf("%d\n", i);
return 0;
}
The limit condition on can only terminate the loop when the condition comes true, not skip iterations. If you want to skip some value, you have to do it at the counting part of for(), or do this with if().
i+=i==3 adds 1 to i when i becomes 3, as i==3 evaluates to 1 if the condition is met and to 0 otherwise (and adding 0 simply does not make any difference).

Resources