tags:

views:

214

answers:

8
for(int i=0 ; i++ ; printf("%d",i));
printf("%d",i);

O/P is 1 . If we take i=1 then there is an absurd output and if i=-1 then output is 01. How is the For loop functioning.Plz Help.Thanx.

+6  A: 

The for loop won't even run - i is 0 when tested in the condition, before being incremented. Also, unless i is defined somewhere before the loop too, the code won't compile because the i in the printf after the loop is undefined.

Where on earth did you take this code from? It's a very grotesque way to write a for loop and I would never use it outside an obfuscated coding contest.

Eli Bendersky
I wouldn't be surprised if it was homework or an interview question. They love asking tricky stuff like that.
cHao
@cHao: I just wish they'd stick to legal, defined, behavior when asking tricky stuff.
David Thornley
i will still be incremented. (Perhaps this is merely bad wording... The loop indeed does not run - and the test condition is indeed checked before 'i' is incremented, but it is still incremented according to that syntax.) That said, the compiler should be able to optimise that out, in this case.
Arafangion
@Arafangion: I didn't suggest `i` wouldn't be incremented it would, but it would also immediately go out of scope, so it's like that proverbial tree in the forest on one hears falling ;-)
Eli Bendersky
+12  A: 

The test part of the for-loop is i++.

Because the ++ (or increment) is post-fix (written after the variable, instead of before it), the increment happens after the statement is evaluated and tested. The test is on 0, which evaluates to FALSE, hence the "loop" exists without ever being run.

Next, the post-fix ++ takes effect, changing i from 0 to 1.

As @paxdiablo pointed out, once the loop exits, i is out of scope. Whatever the final printf is printing, it is a different i, declared and given a value that is not shown in your code.


In the other scenarios, if you start i at 1, then the test is always true, and every number is printed out (until i overflows, and returns to 0).


And finally, if i starts at -1, the test initially passes (-1 is TRUE), the post-fix increment happens, turning -1 into 0, and 0 is printed out.

The loop is run again, this time 0 fails the test, the loop ends, the post-fix increment happens, and the other i (not shown in your code) is printed out after the end of the loop.

abelenky
Careful, that `i` only exists within the scope of the `for`. Whatever `i` is printed out after the loop is a _different_ one (hidden while the `for` loop is running). The loop will have zero effect on that variable.
paxdiablo
excellent catch @paxdiablo. I totally missed that.
abelenky
I do seem to recall some buggy compilers would still let you access that same `i`, would make this code a useful test case, although I surely hope that one doesn't have to deal with such a compiler!
Arafangion
Note that the overflow and return to 0 isn't guaranteed to happen, although it will on every system I've programmed on for the last twenty years.
David Thornley
@Arafangion: Yes, see accepted answer for http://stackoverflow.com/questions/984878/what-is-the-possible-use-for-define-for-if-false-else-for
paxdiablo
@David Thornley: I agree. The spec doesn't guarantee it will happen, but I consider it a safe bet.
abelenky
+2  A: 

In for(int i=0 ; i++ ; printf("%d",i)); the test condition is false (since i++ returns 0), the loop won't run.

Notice the semicolon after the loop. :)

Prasoon Saurav
A: 

This loop ends when i is 0. So if you start above 0, i will be 0... after 2^31 or 2^63 iterations.

florin
You mean (2^32 - 1) or (2^64 - 1), since it'll loop through all the negative numbers too...
cHao
A: 

The ++ is used as post increment. So you when you test the value of i it will be 0 and you don't enter the loop at all. Outside the loop you print the value of i which is now 1

codaddict
Thnx evry1 for ur help.I got it. This question came in one of the GATE papers.
Brite Roy
ths s nt a cllphone.
Adriano Varoli Piazza
@Brite Roy: What's a GATE paper, and why does it insist on invoking undefined behavior?
David Thornley
Gate is an exam held in India.
Brite Roy
@Adriano...ok,I'll take care of this.
Brite Roy
@Brite: they are asking such a stuff in an official national exam? screwed.
Jens Gustedt
+1  A: 

This looks like mangled code. I can't believe it's intentional.

The second part of the for() statement specifies the condition for the loop to terminate. If the condition evaluates to true, then the loop ends, otherwise it iterates.

In this case, the second part of the statement is i++. This would normally be in the third section of the if() statement. By putting in the second part, you're forcing the loop to only exit if i++ evaluates to false, ie zero. Therefore, if i starts less than zero, you'll get iterations until it reaches zero, otherwise you'll get an infinte loop.

As I said, ++ would normally be in the third part of the statement, so on the face of it, it looks like someone has removed the middle section of the if() statement, got a compile error, and tried to fix it by jamming the printf() on the end. Messy.

Spudley
A: 
for(int i=0 ; i++ ; printf("%d",i)); printf("%d",i);

is equivalent to

int i = 0; 

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

printf("%d",i);

When i = 0 initially, i++ is 0 (and thus false), so the loop never gets executed. But i gets set to 1, so the last printf prints 1.

When i = -1 initially, then i++ is -1 (nonzero, so true), so the loop body executes. After i++, i is 0, so the first printf prints 0. We have now reduced the problem to the previous case, so the rest of the output is 1. So the overall output is "01", with the 0 and 1 being right next to each other because you didn't put any whitespace in your printf format string.

When i = 1 initially, then the loop gets executed with i = 1, then i = 2, then i = 3, ..., then i = 2147483647 (or whatever INT_MAX is), then wraps around to i = -2147483648, then i = -2147483647, then i = -2147483646, and eventually wraps around to 0 after having printed billions of numbers.

dan04
grrt Explanation dan04.Thnku so much.
Brite Roy
Sorry to nitpick but your equivalent code _isn't_. Whatever `i` is being printed in that second `printf` is not the one being printed in the first (the scope of which is limited to the `for` itself). Other than that, not bad. Better would be something like `{ int i = 0; while (i++) { printf("%d",i); } } printf("%d",i);
paxdiablo
@Brite Roy: The last paragraph isn't correct according to the Standard, although it will work on most modern systems. Signed integer overflow is undefined in C and C++. Also, the `i` in the last `printf` is not the `i` from the loop, if this is C or standard C++.
David Thornley
It is also an incorrect explanation, although some compilers would allow it to work like that.
Arafangion
+2  A: 

It shouldn't compile, unless there's an i declared previously.

The code would be illegal in C90, since there were no declarations allowed except at the beginning of blocks. In C99, the declaration of the i in the for loop is legal, but its scope is the loop, and does not extend beyond it. This would also be true in standard C++, but in pre-standard C++ the scope did extend to the end of the enclosing block. It is possible, of course, that the compiler doesn't conform to any published standard, and in that case we can't say what absolutely should happen.

A for loop has three clauses. The first is run at the very beginning and nowhere else, and (in C99 and C++) may be a declaration. It establishes the starting value of i.

The second clause is run before the loop body. If it evaluates to false, the for statement ends immediately. Since i is an int, the only false value is 0. In this case, the i++ returns the current value of i and increments it for later use. Therefore, if i is 0, the for loop does nothing. If i is 1, then i will be incremented until i is 0 or something else happens. This is actually undefined behavior, since i is a signed integral type, but what will usually happen is that it will increment to the most positive possible int, then turn into the most negative possible int, and then increment until it's 0 and the loop stops. If i starts at -1, then in the first run it isn't 0, but it will be for the second run.

The third clause, which here does the printing, is run after the loop body. It's normally used to increment whatever the loop is doing, which may be running through a range of integers or down a chain of pointers in a linked list or something else. It has no effect other than being executed.

The body of the for loop is empty, as shown by the ; immediately after the closing parenthesis. This means that, after executing the first clause, the execution will be the second and third alternating, with a stop whenever the second clause evaluates to 0.

It's a very odd for statement, in that there's no loop body and the increment is done in the second clause, but it's legal (unless there's arithmetic overflow, which will happen if i is positive to start). The undefined i immediately following isn't.

David Thornley
Thnx Sir for this perfect explanation..
Brite Roy