views:

148

answers:

8

I have been trying out some basic exercises involving loops.

Can someone tell me why the following snippets have different outputs?


While Loop

while (i<3)
{
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

Output

(0 0) (0 1) (0 2)

For Loop

for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
            printf("(%d %d) ",i,j);
    }

Output

(0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2) 

Aren't they supposed to have the same output?

+5  A: 

You never reinit the vars in the while loop.

dcp
If you are talking about the answer of Ninefingers, variable *j*, then it is not reinitialized in *its* loop, so it is correct.
Erkan Haspulat
@Erkan H - I'm not talking about the answer of NineFingers, we posted nearly within a couple seconds of each other, how could I have been talking about his/her answer?
dcp
I misunderstood your post, sorry.
Erkan Haspulat
+15  A: 

Try:

while (i<3)
{
    j = 0;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

In your code, what is happening is simple - for the first loop i = 0, j = 0, 1, 2, 3 for the second i = 1, j = 3...

Ninefingers
In the code as-was, the 2nd while never fires again because j == 3 still. This is the right way to make the for and while the same.
Will Eddins
Adding a line to explicitly initialize the variable i would be helpful in making the problem more clear.
semaj
+2  A: 

Inner while loop executes only once, because your j variable equals 3 and is never reseted.

Nikola Smiljanić
+9  A: 

You aren't reinitializing the variable before the while loop starts, like in the for loop. Try this:

i = 0;
while (i<3)
{
    j = 0;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}
Mark Byers
A: 

in the while statement your value for j remains at 3 and no longer executes. it is reset in the for loop.

FiveTools
+2  A: 

Can someone tell me why the following snippets have different outputs?

Yes, they are not equivalent. To make the two snippets of code equivalent, you need to initialize i = 0 and especially j = 0 inside the while loop like so:

i = 0;
while (i < 3) { 
    j = 0;
    while(j < 3) { 
        printf("(%d %d)", i, j); 
        j++; 
    } 
    i++; 
} 

Remember that

for(init-statement condition; expression) {
    statement
}

is translated to

init-statement
while(condition) {
    statement
    expression
}

In particular,

for(j = 0; j < 3; j++)   
    printf("(%d %d)", i, j);   

is translated to

j = 0;
while(j < 3) {
    printf("(%d %d)", i, j);
    j++;
}

As such, you are missing the very key j = 0 initialization before entering the inner while loop as well as the i = 0 initialization before entering the outer while loop.

So to wrap it all up, the translation of

for(i = 0; i < 3; i++) { 
    for(j = 0; j < 3 ; j++) 
        printf("(%d %d)", i, j); 
}

is (first pass)

i = 0;
while(i < 3) {
    for(j = 0; j < 3; j++)
        printf("(%d %d)", i, j);
    i++;
} 

and finally

i = 0;
while(i < 3) {
    j = 0;
    while(j < 3) {
        printf("(%d %d)", i, j);
        j++;
    }
    i++;
}
Jason
+1 for the extremely thorough answer. :)
technophile
A: 

As others said, you haven't reset the your j variable. In general I can say

s1;
while(condition){
    s0;
    s2;
}

... is not equal to ...

for(s1;condition;s2){
    s0;
}

... because if s0 contains a continue then s2 is not executed in the first case and executed in the second.

Secondly the variable declarations in s1 will be limited to the loop in the second case. This is used to be desired, but sometimes not. In that case you can do the declaration before the loop.

Notinlist
A: 

This is why you declare your variables in the scope they should exist in. For example, this should return the same values as you'd get from the for.

while (i<3)
{
    int j;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

Why? Because j is recreated for each loop of the outer while.

R. Bemrose