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
Related
The semicolon has been added after the first while loop, but why is the value of the i variable 3 here, where j is 2?
#include<stdio.h>
int main()
{
int i=1;
while(i++<=1);
printf("%d",i);
int j=1;
while(j++<=1)
printf("%d",j);
return 0;
}
Both while loops run once (and once only); the difference is that, in the second case (the j loop) you are printing the 'control variable' inside the loop but, for the first case, you are printing it after the loop condition has evaluated to false. Also note that, in the first case, the semicolon immediately following the while statement defines the body of that loop as empty1.
Let's break down the first loop into steps:
On the first test of the condition, i++ evaluates to 1 and then i is incremented – so the loop runs.
On the second test, i++ evaluates to 2 (so the loop doesn't run) but i is still (post-)incremented, leaving it with the value of 3 (as shown in the output).
The same thing happens with j in the second loop but, in that case, as previously mentioned, you are displaying the value in the body of the loop (on its only run), so you see the value after the first (post-)increment.
As noted in the comments, if you add another printf("%d", j); after the body of the loop (which, in that case, consists of a single statement), you will see that j, too, has the value 3 when that loop has finished.
1 More precisely, the semicolon (on its own) defines a null statement, which forms the body of the while loop.
It is often helpful to clarify such 'null loops' by putting the semicolon on a line by itself (some compilers, with full warnings or static analysis enabled, may even suggest you do this):
#include<stdio.h>
int main()
{
int i = 1;
while (i++ <= 1)
; // Body of loop - Null Statement
printf("%d", i); // Loop has finished
int j = 1;
while (j++ <= 1)
printf("%d", j); // Body of loop
// Loop has finished
return 0;
}
For starters let;s consider how the postfix increment operator works. From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).
Now consider this while loop
int i=1;
while(i++<=1);
In the first iteration of the loop the value of the expression i++ as the value of its operand that is 1. So the loop will iterate a second time, Due to applying the side effect to the variable i it will be equal already to 2 when the expression i++<=1 will evaluate the second time.
Now the value of i is equal to 2 and is greater than 1. so the loop will be interrupted. Again due to applying the side effect of the postfix increment operator to the variable i it will be equal to 3. This value is outputted in the following call of printf.
In simplest terms,
consider three things for each iteration of first while loop:
first iteration:
int i = 1;//initialization
while(i++<=1); //1. i evaluated as 1,
//2. loop condition is true causing loop to iterate again.
//3. ...but not before ++ causes i==2.
second iteration:
while(i++<=1); //1. i evaluated as 2,
//2. loop condition is false causing loop to eventually exit
//3. ...but not before ++ causes i==3.
printf is not included in the while loop (because of the semicolon) but
when program flow finally reaches printf("%d",i); the value of i is output as 3
In the second loop, because printf is included in the while construct, it will output the value of j for each iteration. For the same reasons as in loop one, it will also iterate only twice, and its values at time of output will be 2 & 3.
Using a debugger to set break points, and a watch on i, you can step through code such as this to see the sequence of these effects as they happen.
For explanation porpouses look at this example:
int main()
{
int i=1;
while(i++<=1)
printf("%d",i);
printf("%d",i);
}
The Output is:
2
3
Ok let's dive into the programm procedure:
Declaring i (i = 1)
while checking Condition and it's true because i++ returns 1(old Value). That's because the ++ are after the i. If you would code it like this ++i than it returns 2(new Value) (i = 2)
execute printf (i = 2)
while checking Condition and it's false because i++ returns 2 and 2 is not <= 1 (i = 3)
execute printf (i = 3)
Do you understand?
If it solved your thoughts jumble ;) mark it as answer.
You've got many answers already so I won't try to explain it in words but with an illustration in code. I've added two functions:
One that acts like a prefix increment operator (++i)
One that acts like a postfix increment operator (i++)
I'm only using the postfix version in the program though. I've added logging to the function so you can see how it works.
#include <stdio.h>
// this acts as if you put ++ before the variable
int preinc(int* p) {
++*p;
return *p;
}
// this acts as if you put ++ after the variable
int postinc(int* p) {
int rv = *p;
++*p;
printf("returning %d but incremented to %d\n", rv, *p);
return rv;
}
int main() {
int i=1;
while(postinc(&i) <= 1);
printf("end result: %d\n---\n", i);
int j=1;
while(postinc(&j) <= 1)
printf("in loop: %d\n", j);
printf("end result: %d\n", j);
}
Output:
returning 1 but incremented to 2
returning 2 but incremented to 3
end result: 3
---
returning 1 but incremented to 2
in loop: 2
returning 2 but incremented to 3
end result: 3
If you add the semicolon in the end of the while you will take: i = 3 and j = 3(IN THE OUTPUT).
If you add the semicolon only in the end of the printf and not to the while you will take i = 2 and j = 2(IN THE OUTPUT), but in the end you will, also, have the values
i = 3 and j = 3.
This happens because the "i" variable is incremented only after the first iteration of the loop, in which the empty statement (terminated by the semicolon) is evaluated.
that is why it is highly recommended to do "++i" rather than "i++", because then the incrementation is performed prior to the evaluation.
if you flip it here, you will see that i will be equal to 2 as well, regardless of the presence of the semicolon
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).
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.
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
guys i'm new at programming and i was surprised by the result of post increment value, now i'm bound by confusion after i found out and executed the code below, if for loop says
1. initialize
2. check for condition if false terminate
3. incrementation.
where does i++ happens? where does i value is equal to 1?
int main()
{
int i, j;
for (int i =0; i<1; i++)
{
printf("Value of 'i' in inner loo[ is %d \n", i);
j=i;
printf("Value of 'i' in outter loop is %d \n", j);
// the value of j=i is equals to 0, why variable i didn't increment here?
}
//note if i increments after the statement inside for loop runs, then why j=i is equals to 4226400? isn't spose to be 1 already? bcause the inside statements were done, then the incrementation process? where does i increments and become equals 1?
//if we have j=; and print j here
//j=i; //the ouput of j in console is 4226400
//when does i++ executes? or when does it becomes to i=1?
return 0;
}
if Post increment uses the value and add 1? i'm lost... Please explain... thank you very much.
I'm not really sure what you're asking, but sometimes it's easier for beginners to understand if rewritten as a while loop:
int i = 0;
while (i < 1)
{
...
i++; // equivalent to "i = i + 1", in this case.
}
Your loop declares new variable i and it shadows the i declared earlier in main(). So if you assign i to j outside of the loop, you are invoking undefined behaviour because i is not initialised in that context.
Prior to the first iteration, i is initialised to 0. This is the "initialize" phase, as you called it.
The loop condition is then evaluated. The loop continues on a true value.
The loop body is then executed. If there's a continue; statement, that will cause execution to jump to the end of the loop, just before the }.
The increment operator is then evaluated for it's side-effects.
Hence, it is after the first iteration that i changes to 1. i keeps the value 1 for the entirety of the second iteration.
It looks like you have a clash of variable names: i is declared before the loop, and also inside the loop.
The i that is declared in the for statement is the only one that will ever be 1. It will be one just after the body of the loop is executed.
Try setting a breakpoint and using the debugger to step through the loop whilst you watch the value of the variable (here's a video of what I mean by stepping with the debugger).
To remove the ambiguitity of having two variables called i you could change the for loop to:
for (i = 0; i < 1; i++) // remove the `int`
this will ensure that there is only one i in your code.
A comment on #CarlNorum's answer which wouldn't look good as a comment:
The C Standard defines
for ( A; B; C ) STATEMENT
as meaning almost the same thing as
{
A;
while (B) {
STATEMENT
C;
}
}
(where a {} block containing any number of statements is itself a kind of statement). But a continue; statement within the for loop will jump to just before the next statement C;, not to the next test of expression B.
for (i=0; i<x; i++)
Is equivalent to
i=0;
while(i<x) {
// body
i = i + 1;
}