I have a doubt about the for loop of the following code in C:
main()
{
int i=1;
for(;;)
{
printf("%d",i++);
if(i>10)
break;
}
}
I saw this code in a question paper. I thought that the for loop won't work because it has no condition in it. But the answer says that the code has no error. Is it true ? If true, how ?
The regular for loop has three parts:
Initialization
Condition
Increment
Usually they are written like this:
for (initialization; condition; increment) { statements }
But all three parts are optional. In your case, all parts are indeed missing from the for loop, but are present elsewhere:
The initialization is int i=1
The condition is if (i>10) break
The increment is i++
The above code can be equivalently written as:
for (int i=1; i <= 10; i++) {
printf("%d", i);
}
So all the parts necessary for a for loop are present, except they are not inside the actual for construct. The loop would work, it's just not a very readable way to write it.
The for (;;) loop is an infinite loop, though in this case the body of the loop takes actions that ensure that it does not run forever. Each component of the control is optional. A missing condition is equivalent to 1 or true.
The loop would be more clearly written as:
for (int i = 1; i < 11; i++)
printf("%d", i);
We can still debate whether the output is sensible:
12345678910
could be produced more easily with:
puts("12345678910");
and you get a newline at the end. But these are meta-issues. As written, the loop 'works'. It is syntactically correct. It also terminates.
You are not specifying any parameters or conditions in your for loop, therefore, it would be an endless loop. Since there is a break condition based on another external variable, it would not be infinite.
This should be re-written as:
for (int i = 1; i <= 10; i++)
printf("%d",i++);
It's an infinite loop. When there is not a condition in for and we use ;; the statements in the body of for will be executed infinitely. However because there is a break statement inside it's body, if the variable i will be greater than 10, the execution will be stopped.
As it is stated in MSDN:
The statement for(;;) is the customary way to produce an infinite loop which can only be exited with a break, goto, or return statement.
For further documentation, please look here.
Even if a for loop is not having any condition in it, the needed conditions are specified inside the for loop.
The printf statement has i++ which keeps on increasing the value of i and next we have if statement which will check if value of i is less than 10. Once i is greater than 10 it will break the loop.
Related
So, I have been studying iterative statements for a report. While I was reading, I came across the developmental history of definite iteration and eventually learn the for loop. We know that the syntax for the for loop in C,C++, and java is
for (expression1; expression2; expression3)
statement
And it says here that we can omit any of the expression and that it is legal to have a for loop that look like this
for (;;)
My question is how does that work? I cant find any more resources for this one.
A for loop declared as:
for (init-statement; condition; iteration-expression) body;
Is equivalent to:
init-statement;
while (condition) {
body;
iteration-expression;
}
It's easy to see how init-statement or iteration-expression could be omitted. If the condition is omitted, it is assumed to be true.
A reasonable resource that explains this is the Explanation section of the for loop documentation at cppreference.com.
Basically, for (;;) is legal, but you will need to put something inside the body of that for loop, otherwise the loop will never stop.
int counter = 0;
int limit = 5;
for (;;) {
if (counter > limit) break;
counter++;
}
I am running a C program with an infinite for loop:
for(;;)
{
//Statement
}
Why is it running an infinite number times, even though we have not specified the loop's initialization, condition and incrementation?
What do the "blank" values mean?
Here's the basic syntax of a for loop.
for(clause-1; expression-2; expression-3) statement;
According to The C Programming Language by K&R, both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a non-zero constant. And as we know, any non-zero value means "true" in C.
P.S.: Though the K&R book is quite outdated, it's considered as the Bible of C by many.
The loop only breaks when the condition is false. Since there is no condition, nothing can be false, and the loop doesn't break.
the for(;;) statement is the same as the while. If you "convert" the for(;;) it will be something like this:
for(i = 0; i < n; i++)
{
//Do stuff
}
to this
i = 0;
while( i < n )
{
//Do stuff
i++;
}
So if the middle statement has nothing in it, it will run forever
EDIT:
In the third part of the loop you can do anything. You could even to this:
for(i = 0; i < n; i++, /*Do stuff*/){}
In this for loop statement
#include<stdio.h>
int main()
{
static int i;
for(++i;++i;++i) {
printf("%d ",i);
if(i==4)
break;
}
return 0;
}
Variable i is at first 0. The arguments in the for-loop at 1st round are 1st ++i: i = 0 + 1 = 1 2nd ++i: i=1+1=2 So, in first loop I have this for(i=1; i<2; ++i); or for(i=1; i<=2; ++i);?EDIT I found this example online in a test about C. I run this (inside the for-loop , I have a break point so after some loops it breaks) but I was just guessing the behavior of that so I asked it here to be sure. I am learning now C so stupid questions exists for me. Its better to ask, than not.
In the second argument it is actually ++i!=0, The loop is interpreted as
for(++i;++i!=0;++i)
If you start with a positive i or 0, it will be an infinite loop and will invoke undefined behavior when i reaches INT_MAX.
If i was -Ve initially the loop may stop at a defined run.
EDIT: As you changed your question, Your code will not crash, but you can clearly understand the dry-run by replacing the second ++i with ++i!=0.
So the 1st iteration becomes:
(i=1;2!=0;++i/*this will execute later*/)
2nd iteration becomes:
i=3 //this is from the 1st iteration last part.
(/*initialization is done 1st time only*/;4!=0;++i/*again, this will execute after this iteration*/)
It will print 2 4.
Before the for loop, i will be 0. It hasn't been assigned anything yet, and static variables are guaranteed to be zero initialized before they are first used.
It will execute the first ++i in the for loop, since that expression is evaluated once at the beginning of the loop. i will be 1.
It will execute the second ++i, because that is evaluated BEFORE every loop to see if it should run an iteration of the loop. i will be 2.
It will run the loop body. This will print 2.
The if condition won't be true so it won't break.
It will execute the third ++i in the for loop statement, since it evaluates that AFTER every iteration. i will be 3.
It will execute the second ++i again, since it needs to see if it needs to run another loop. It will be nonzero, so it will run another loop. i will be 4.
It will print 4.
The if condition will be true, it will break out of the loop.
However, it is a nonsense way to do it. This is a more appropriate way to do that:
int i;
for (i = 2; i <= 4; i += 2)
printf("%d ", i);
or better yet:
printf("2 4 ");
static int i;
While the C standard guarantees that variables with static storage duration are initialized to 0, you should not abuse that. Always initialize your variables, either at the line where they are declared or in runtime. So change this to static int i=0;
The first ++i is indeed equivalent to having i=1 there. Esentially your loop does this:
for(i=1; loop_until_program_crash; i++)
If you have a break inside the loop, then the loop is likely poorly written. If you know in advance when the loop should end, then that condition should be inside the for loop condition. If you don't know in advance, then use a while loop instead.
It should be :
for(i=1; i<=2; ++i);
static int i=0;
for(++i;++i<=2;++i)
{
printf("4rth :%d\n",i);
}
see : http://ideone.com/TGLYlL
Small question just to clarify.
In ZX-Spectrum BASIC compiler there is FOR TO STEP NEXT looping, where TO is unconditional:
10 FOR i=1 TO 5 STEP 1
I've tried similar practice in C
for (i=1; i==5; i++);
and the of course loop does not work (== is never true here)... so the question is:
Is in C FOR loop we should always use a CONDITION to stop the loop (I mean CONDITION in parentheses of the FOR statement), like FOR (i=0; i<6; i++);
The correct translation of:
for i = 1 to 5 step 1
would be:
for (i = 1; i <= 5, i++)
In other words, a loop running five times with the control variable set to 1, 2, 3, 4 and 5 on sequential iterations.
There are other variations you could use such as different conditional operators and different termination values, but the one shown most matches the BASIC variant while still protecting you in the case where your step may be more than one (such as for i = 1 to 4 step 2).
Keep in mind that C arrays are 0-based so, if you're using that i to access an array, it needs to run from 0 to n-1, not 1 to n. If you just want the variable for other purposes (such as printing out the numbers one through five inclusive), the 1..n variant is okay.
You could use
for (i = 1; i != 6; i++);
But it would be better to use i = 0 ... i < 5, in case you alter i inside of the loop. It also communicates what you are doing better.
There is no any restriction that you must use the conditional statement in the for loop..
You also use this conditional statement in the body of for loop as follow....
for(int i=0;;i++)
{
if(i>=5)
{
break;// to break the loop
}
}
if you not use the conditional statement at in the for loop or in the for loop body then the loop goes into the infinite state as follow....
for(int i=0;;i++)
{
//any statements
}
Because In the for loop all three part are optional (initialization , conditional , incri/decri)
int i=0
for(;;)
{
if(i>=5)
{
//any statements
}
i++
}
Loop conditions are not necessary you can write loops like
for(int i=0;;i++)
{
//body
}
but note that body of the loop should contain some break statement else loop executes infinite time
There are two problems in your code, you shouldn't use a ; after your loop head, and you can use < or <= in your condition part like this:
for(int i=1; i<=5; i++){}
so it should be a condition but you do not have to use an inequality you can use any other condition but it should be finished a time
Why does it tend to get into an infinite loop if I use continue in a while loop, but works fine in a for loop?
The loop-counter increment i++ gets ignored in while loop if I use it after continue, but it works if it is in for loop.
If continue ignores subsequent statements, then why doesn't it ignore the third statement of the for loop then, which contains the counter increment i++? Isn't the third statement of for loop subsequent to continue as well and should be ignored, given the third statement of for loop is executed after the loop body?
while(i<10) //causes infinite loop
{
...
continue
i++
...
}
for(i=0;i<10;i++) //works fine and exits after 10 iterations
{
...
continue
...
}
Because continue goes back to the start of the loop. With for, the post-operation i++ is an integral part of the loop control and is executed before the loop body restarts.
With the while, the i++ is just another statement in the body of the loop (no different to something like a = b), skipped if you continue before you reach it.
The reason is because the continue statement will short-circuit the statements that follow it in the loop body. Since the way you wrote the while loop has the increment statement following the continue statement, it gets short-circuited. You can solve this by changing your while loop.
A lot of text books claim that:
for (i = 0; i < N; ++i) {
/*...*/
}
is equivalent to:
i = 0;
while (i < N) {
/*...*/
++i;
}
But, in reality, it is really like:
j = 0;
while ((i = j++) < N) {
/*...*/
}
Or, to be a little more pedantic:
i = 0;
if (i < 10) do {
/*...*/
} while (++i, (i < 10));
These are more equivalent, since now if the body of the while has a continue, the increment still occurs, just like in a for. The latter alternative only executes the increment after the iteration has completed, just like for (the former executes the increment before the iteration, deferring to save it in i until after the iteration).
Your increment of i is after continue, so it never gets executed
while(i<10) //causes infinite loop
{
.........
continue
i++
......
}
In any loop, continue moves execution back to the top of the loop, not executing any other instructions after the continue statement.
In this case, the for loop's definition is always executed (per standard C), whereas the i++; statement is NOT executed, because it comes AFTER the continue statement.
Because the third part of the for is always executed.
continue statement jumps the control to the end of the statements in current iteration of loop i.e. it skips the execution of the statements in the current iteration and moves to the next iteration of the loop.
With while loop, continue statement causes control to reach the end of statements (including increment statement), thus causing loop to continue forever.
With for loop, continue statement jumps the control to end of statement and excutes the increment statement (In for loop, increment statement is considered seperate from the statments written within the body of the loop).
for loop holds condition statements and increment, so when the condition is satisfied it goes to execute the statement inside for loop,but if write continue statement than it will again reached to first line of for loop i.e. increment and checking of condition statement, if satisfied than again comes in for execution.
For while loop it just checks the condition statement and if condition satisfied it goes for the execution of statements in the while loop.
so continue will not execute any line after it.and hence your condition satisfied every time and goes for the infinite loop.
continue bypasses the rest of the block and begins again at the top of the block if the conditional of the loop is met.
The next question is: "What do I do, then?"
There are two answers I can think of.
Example:
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #1: Manually Increment
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
i++;
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #2: A uniquely valid application of goto*
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
goto foo_next;
}
/*...*/
foo_next:
i++;
} while ( /* loop conditional */ );
}
goto is valid in this case because incrementation in two places is technically the same instruction. This solution is especially relevant when the per-iteration-volatile variables are more complex; such as, setting multiple variables or modifying a value with an equation or function.
In the event of a single increment or decrement statement, Solution #1 may prove favorable; however, it should be noted that: if the code is modified after such an implementation, one must remember to update both instances of the statement (which may be prone to bugs, especially if the modifications take place after an extended period of time**). Therefore, I highly reccomend Solution #2.
*Some consider any and all use of goto bad practice. I recommend you decide for yourself, and leave you this: google for "c goto bad"
**A comment reminding of this necessity may suffice, but — if my advice has been followed — the per-iteration-volatile variables in are restricted to a single statement. And I quote:
There is never a reason to comment a single line
-Linus Torvalds (source: http://yarchive.net/comp/linux/coding_style.html)