0

Apropos the question "Why does using the same count variable name in nested FOR loops work?" already posted in this forum,a count variable "i" defined in each nested loop should be considered a new variable whose scope is limited to that loop only.And we should expect that variable's value to be erased and overridden by the value of "i" which was in the outer loop (before control passed to inner loop).But in my following code, when the control comes out of the inner loop,instead of the variable "i" having the value 0 (which was it's value in the first iteration of outer loop,before control passed to inner loop),it continues to have the value 10 instead (which it got in last iteration of inner loop).Then this 10 is incremented to 11 and hence the condition of the outer loop in not satisfied and the outer loop exits.

I had expected my program to print the numbers 0 to 9 horizontally 10 times, in 10 different lines.But it prints just for one line and exits.

And here's another thing to it--If I use any number greater than 10 in the outer loop condition (i<=10),then it creates an infinite loop.According to my reasoning, it happens because i gets a value of 11 after the first iteration of outer loop and hence if condition is <=11 or more then the outer loop comes to another iteration.Whereupon i is again initialized to 0 in inner loop and the cycle continues.

Sorry if I couldn't put my question very clearly.All I want to ask is, isn't the inner i supposed to be a different variable if we are to assume the linked question on this forum is correct?Why then the value of i continues to hold on after we exit inner loop,instead of reverting to the value of i that was there when we entered the inner loop?

#include <stdio.h>

int main()
{
    int i;

    //for (i = 0; i <= 11; i++)  Creates infinite loop if this condition is used instead
    for (i = 0; i <= 9; i++)    
    {
        for (i = 0; i <= 9; i++)
        {
            printf("%d ", i);
        }
        printf("\n");
    }
}

OUTPUT : 0 1 2 3 4 5 6 7 8 9

PS: As a secondary question, is it impossible to print the number 0 to 9 horizontally, in 10 different lines, using nested for loop if we use the same count variable in each loop,as I have done here? (Ignore this secondary question if it's not relevant to main question)

4
  • In addition to the very clear answers you got, I would add this is anyway a bad idea, from my perspective. Commented Apr 2, 2013 at 14:23
  • If I initialize the variable each time in for loop I get the error " 'for' loop initial declarations are only allowed in C99 mode|".I am using CodeBlocks on windows. Commented Apr 2, 2013 at 14:23
  • @Bartdude Yeah, that's right.I was only experimenting to check out the concept of scope.I never use the same variable name in nested loops. Commented Apr 2, 2013 at 14:24
  • 1
    in older C compilers (including, for instance, visual studio when compiling a *.c file) variable declarations were only allowed at the beginning of blocks, in this case you have to declare 2 separate variables (say i and j - which is a good idea in any case) Commented Apr 2, 2013 at 14:25

6 Answers 6

7

The answer you linked to is using different variables with the same name, you're simply using the same variable.

Compare:

for(int i = 0; ...

to:

for(i = 0; ...

The former declares a new variable called i, which is how you nest loops like the linked-to answer. Not that I would ever (ever!) recommend doing so.

As you've noticed, support for the former syntax wasn't added to C until C99.

Sign up to request clarification or add additional context in comments.

2 Comments

If I initialize a variable in for loop I get the error " 'for' loop initial declarations are only allowed in C99 mode|".I am using CodeBlocks on windows.
You need to compile in C99 mode. Most compilers have a -std=c99 option.
2

If i were defined in each loop then the behaviour would be as your linked question. In your example you only define i once, outside any loop, then reuse it

int i;

for(i=0; i<=9; i++)    
{

   for(i=0; i<=9; i++)
{

is not the same as

for(int i=0; i<=9; i++)    
{

   for(int i=0; i<=9; i++)
{

Comments

2

If you want each for loop to have its own i, you need to create i individually for each. As-is, you have exactly one i that's defined outside both loops, so the modifications done by one loop affect the value seen by the other.

int i;
for (i=0; i<10; i++) {
    int i;           /* define another i for the inner loop */
    for (i=0; i<10; i++)
        printf("%d\t", i);
    printf("\n");
}

Note that I'd generally recommend against this -- while the compiler has no problem at all with having two variables with the same name at different scopes, code like this where it's not immediately obvious what i is being referred to when may well confuse people reading the code.

Comments

0

All I want to ask is, isn't the inner i supposed to be a different variable

no, there is only one declaration, so only one variable

Comments

0

Sorry - late response, but couldn't help but notice:

The reason it "works" is that the inner loop resets i to zero, prints & increments i, and returns to the outer loop - at which point i>9 so the outer loop exits.

There is only one iteration of the outer loop and the values printed are entirely determined by the inner loop. It's not a question of scope, it's the fact you reassign new values to i in the inner loop.

Comments

0

PS: As a secondary question, is it impossible to print the number 0 to 9 horizontally, in 10 different lines, using nested for loop if we use the same count variable in each loop, as I have done here? (Ignore this secondary question if it's not relevant to main question)

Of course you can, but you need a more complex format string for your printf.

printf("%d ",i);

The above statement works by printing I, immediately followed by a space, and leaving the carriage where the print stops.

The effect that I think you have in mind is something like the following.

0
  1
    2
      3
        4
          5
            6
              7
                8
                  9

To make that happen, you need a couple of changes to your printf statement, as illustrated in the following complete program.

// MarchingDigits.cpp : Defines the entry point for the console application.
//

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    for ( int i = 0 ; i < 10 ; i++ )
    {
        printf ( "%*d\n", ( i > 0 ? i + 1 : i ) , i ) ;
    }   // for ( int i = 0 ; i < 10 ; i++ )

return 0;
}       // int main

The output generated by this program is as follows.

0
 1
  2
   3
    4
     5
      6
       7
        8
         9

There are three fundamental differences between your printf statement and the one that generated this output.

  • Between the opening % and the closing d, I inserted an asterisk where the width goes.
  • I replaced the trailing space with a newline.
  • Between the format string and your integer argument i, I inserted another argument, in the form of a ternary expression, i > 0 ? i + 1 : i, which says, in effect, if I is greater than zero, set the width to i + 1, otherwise set the width to i. Although the else block sets the width to i, which happens to be zero, this works because printf guarantees never to truncate the output.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.