What is the difference when we declare variable before using in loop and when define variable in loop.
I am talking about this situation
int i;
for(i=0; i<100; i++);
and
for(int i=0; i<100; i++);
In the former case, you can access i outside the for-loop. This can be advantageous if you have a conditional break in your loop, for example:
int i = 0;
for (i = 0; i < 100; i++) {
if (someUnexpectedConditionHappens()) {
break;
}
// do something
}
printf("The loop has been executed %d times", i);
In the first case it is supposed that variable i will be used also after the loop as for example
int i;
for(i=0; i<100; i++);
printf( "i = %d\n", i );
Nevertheless it would be much better to write the following way
int i = 0;
for( ; i<100; i++);
printf( "i = %d\n", i );
In this case we will get a valid readable code without a need to bother what is done within the loop as for example
int i = 0;
/* some loop used i */
printf( "i = %d\n", i );
That is even if the variable will not be changed (assigned) in the loop or in some other code instead of the loop (usually each code has a tendency to be changed) nevertheless we will get a valid result.
In the second case it is supposed that variable i will be used only within the loop
for(int i=0; i<100; i++);
We need not its value outside the loop. So in this case the life of the variable is limited by the body of the loop. Outside the loop it will be invisible and not alive.
It's the "scope". In the second case, you can only use the variable within the for loop. In the first case - in the entire containing block.
In the first case, i can be accessed outside the loop within the current block. In C89, you cannot declare variables in the loop so you'll have to stick to this method.
In the second case, i cannot be accessed outside the loop. Declaring variables in the loop is a C99 feature.
When you do it before the loop, the variable is then available outside the loop as well.
Whereas when you do it inside it, it is a local variable that can only be used inside the loop.
Also, you can declare a variable inside a loop when using C99 standard. But it does not work for example for C90. So be careful with that.
In the first case, i is accessible outside the for loop.
In the second case, the scope of i is restricted to the for loop body.
Arguably the second case gives you better program stability since the use of i outside the for loop is often unintentional.
Related
In C Primer Plus, the author says that
A C99 feature, mentioned earlier, is that statements that are part of
a loop or if statement qualify as a block even if braces (that is, { }
) aren’t used. More completely, an entire loop is a sub-block to the
block containing it, and the loop body is a sub-block to the entire
loop block.
I guess the loop body means the printf(...) statement in the example below. But what do these these two bold words mean? : ".. an entire loop is a sub-block to the block containing it,..." It would be nice if you could explain it using the example below!
for(int n =1;n<3;n++)
printf("%d \n",n);
It is phrased a bit badly, but it's quite simple:
for(int n =1;n<3;n++) // <-- loop
printf("%d \n",n); // <-- block
The loop body is as you said the printf() in this case, and in general, trying to keep my answer as minimum as possible, this is the format:
for(...; ....;)
body_of_loop
The sub comes into play when you have nested loops, or if statements. For example, a double for loop:
1. for(int i = 0; i < 10; ++i)
2. for(int j = 0; j < 10; ++j)
3. printf("hi\n");
More completely, an entire loop is a sub-block to the block containing it, and the loop body is a sub-block to the entire loop block.
So, line 2 is an entire loop and it's a sub-block to the block that it is part of. The block of the exterior for loop is lines 2 and 3.
If you have a code block, for example:
while(1) <-- code block (contains if [that contains printf])
if(2) <-- sub block (contains printf)
printf("3"); <--- part of if block
the printf is considered to be a part of the if block, and the if block itself (now containing the printf as well) is considered a part of the bigger while block. This could go on and on...
while(1)
while(2)
if(3)
for(;;)
i++;
Each of the 3 mid-lines here is a sub block that contains following lines
The C11 standard says, in §6.8.5 Iteration statements
¶5 An iteration statement is a block whose scope is a strict subset of the scope of its
enclosing block. The loop body is also a block whose scope is a strict subset of the scope
of the iteration statement.
I think this is what the statement you quote is attempting to paraphrase.
What this is driving at, somewhat opaquely (welcome to the world of reading standards), is that an iteration statement (while loop, do … while loop or for loop) is treated as a block. This primarily affects the for loop with variable declarations.
Consider:
for (int i = 0; i < max; i++)
printf(" %d", i);
putchar('\n');
The wording means that the code functions as if you had:
{
for (int i = 0; i < max; i++)
{
printf(" %d", i);
}
}
putchar('\n');
This particularly limits the scope of i to the for loop; it is not accessible outside the loop. The loop body being a block whose scope is a strict subset of the iteration statement isn't a big surprise. The surrounding block is less obvious and could be a surprise.
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.
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
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;
}
Several books show me how to correctly write for, while, and do loops.
Lots of online articles compare them to each other.
But I haven't found any place that tells me what not to do. For example, would it screw things up if I change the value of the counter or condition variable within the loop?
I would like an answer that is not machine dependent.
Yes you can change the counter within a loop and it can sometimes be very useful. For example in parsing command line arguments where there is an option flag followed by a value. An example of this is shown below:
Enter the following command:
program -f filename -o option -p another_option
Code:
#include <string.h>
int main(int argc, char** argv)
{
char *filename, *option, *another_option;
if(argc > 1){
for(int i=1; i<argc; i++){
if(strcmp(argv[i],"-f")==0){
filename = argv[++i];
} else if(strcmp(argv[i],"-o")==0){
option = argv[++i];
} else if(strcmp(argv[i],"-p")==0){
another_option = argv[++i];
} else {
printf("Option \"%s\" not recognized, skipping\n",argv[i]);
continue;
}
}
} /* end if argc > 1 */
return 0;
}
The example program automatically increments the counter to access the correct command line string. There are of course ways to incorporate counters etc., but they would only make the code more cumbersome in this case.
As others have pointed out, this is where many people write bugs and one must be careful when incrementing counters within loops, particularly when the loop is conditional upon the counter value.
It is not invalid to change a loop counter inside a loop in C.
However, it is probably confusing to future readers and that's a good reason not to do it.
It depends on what you mean by "screw things up".
If you know what you are doing, you can change counter. The language has no restrictions on this.
Changing the counter variable in the loop is allowed, but be careful to know what you are doing to not create infinite loops by decreasing the variable when you shouldn't be.
Some algorithms actually benefit from this, but of course if you do this it makes your code less readable so make sure you comment what you are doing also.
Yes, you can change the counter and condition variables. They will just be evaluated with the next iteration of the loop.
Definiteley you can.But be careful not to make the loop disorder. Alter a conter in the loop happens a lot in do...while and while.
do{
counter++;
some expressions;
}
while(counter < SOMEVALUE);
Yes, in C/C++/C# You can change the counter etc. in the loop.
Like many other techniques, as long as you know what do you do, it's fine.
For example, this code:
int i;
for (i=0;i<5;i++)
printf("%d\n",i--);
is an infinity loop, but this version of bubble sort:
int *arr,n;
//allocate memory, assign values, and store the length of the array in n
int i;
for (i=0;i<n-1;i++)
if (arr[i]>arr[i+1]) {
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
if (i) i-=2;
}
is fine. (It's not exactly bubble sort. Instead of using nested loops, I go back in the array after swapping members in it)
Be careful changing counter variable inside a loop, not all loops are the same, "while" loop behaves differently. see this example?
No, it is NOT an infinite loop (on some compilers). run it, and see...
i=5;
while (i--)
{
i=100;
printf("%d \n",i)
}
We can change the counter value inside the loop but the final counter value wont be reflected as the for loop wont override the counter value.
here is the example in QTP VB script.
iLast = 4
For i= 1 to iLast
iLast=2
Next
Here the for loop should execute only for 2 times as iLast value is updated to 2 inside the loop but it is executing for 4 times.