14

I was not really clear with the post increment operator that I always used with for loops. My latest and newly acquired understanding of post increment operator is the following:

int a = 5
int b = a++ //a will increment and return back its old value 5
so b = 5

Armed with this new knowledge i decided to understand/apply it to the places where i commonly used the post increment operator as in a for loop . Now it seems like I am lost since I am ending up with the wrong output theoretically

Consider the following code

for(int i=0 ; i< 3 ; i++)
{
  std::cout << i; 
}

First loop

i starts with 0 which is less than 3 so ( increment by 1 however since its i++ it returns old value 0) 
so cout should display 1 // But it displays 0

Second Loop

 i is now 1 which is less than 3 so i++ is applied - Now i is 2 and returns back 1
 so cout should display 2 //But it display 1

Third Loop

 i is now 2 which is less than 3 so i++ is applied - Now i is 3 and returns back 2
 so cout should display 3 //But it display 2

Fourth Loop

 i is now 3 which is not less than 3 so loop exits

Could anyone please clear my understanding and point me in the right direction. The output should be 0,1,2 where am i going wrong ?

Rajeshwar
  • 11,179
  • 26
  • 86
  • 158
  • Your third loop may be optimised away as nothing is using the returned value so it just becomes 3 anyway – EdChum Sep 25 '14 at 08:58
  • 3
    This question is not about post increment operator, but about understanding of for-loop (first processing of loop-expression happens only after first processing of the body of the loop). You can read about it here: http://www.cplusplus.com/doc/tutorial/control/ – Ilya Sep 25 '14 at 08:58
  • I would appreciate it if someone could clear that up – Rajeshwar Sep 25 '14 at 08:58
  • 5
    +1 for "Armed with this new knowledge". – barak manos Sep 25 '14 at 08:59
  • 4
    +1 for being a rare glittering jewel that understands this: `// a will increment and return back its old value 5`, is a far-more-accurate assessment of how post-increment works than 95% of the academics that teach the stuff. – WhozCraig Sep 25 '14 at 09:03
  • The skinny: it's not like `condition = (i++ < 3)` but `i++; condition = (i < 3)`. – SF. Sep 25 '14 at 19:52

3 Answers3

36

What you're missing is when each of those sections of the for statement happen:

for (int i = 0 ; i < 3 ; i++)
//   111111111   22222   333
  • The first bit happens once before any iterations are done.
  • The second expression is evaluated before each potential iteration and, if false, no further iterations are done.
  • The third bit is done at the end of each iteration, before returning to evaluate the second bit.

Now re-read that last bullet point carefully. The i++ is done at the end of an iteration, after the cout << i. And, immediately after that, the continuation condition is checked (the second part).

So the loop is effectively the same as:

{   // Outer braces just to limit scope of i, same as for loop.
    int i = 0;
    while (i < 3) {
        cout << i;
        i++;
    } 
}

That's why you get 0 1 2.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    could you explain the reason why third bit is done at the end of iteration? – Amit Bisht Sep 25 '14 at 11:04
  • 9
    @Co.Aden Because the language specification says so. `for` is `while` with syntactic sugar, because it is such a common construct to do things like incrementation. See page 60 (chapter 3.5) of "The C Programming Language 2nd edition". (or the corresponding place in Bjarne Stroustrup's book on C++). – MattBianco Sep 25 '14 at 11:24
  • Just a quick note: the pre-increment-operator is always faster than the post-increment operator; so use it in for loops – esskar Sep 25 '14 at 14:10
  • 14
    @esskar not its'not http://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i-in-c – edc65 Sep 25 '14 at 14:31
  • 1
    Functionally speaking, then, the `int i = 0` bit is only important for the first iteration. Does that mean after the first - or, initial - iteration, `i = 0` is no longer evaluated? – Thomas Sep 26 '14 at 11:40
  • 1
    @Thomas, ytes, that's the case in both the `for` and the equivalent code I've shown. I'll clarify that in the bullet list. – paxdiablo Sep 26 '14 at 13:09
6

The semicolons in a for loop delimit three different expressions. The value of the third expression is irrelevant to the behavior of the loop. You could replace i++ with ++i and your loop would behave the same; either way, i is incremented by 1.

To observe the behavior of the increment operators, consider the following loops:

for(int i = 0 ; i++ < 3 ; ) cout << i;
/*                      ^^^ Nothing here!                      */

Note that the third expression is empty. The output is 123—0 is skipped because the test, including increment, occurs before every iteration of the loop.

How does the postincremented loop behave compared to a similar one with the preincrement operator?

for(int i = 0 ; ++i < 3 ; ) cout << i;

Now the output is 12—3 is not printed because the conditional test sees the value 3 as soon as it is incremented to that, so the loop exits.

Jacob Krall
  • 28,341
  • 6
  • 66
  • 76
  • I feel like the explanation above is missing some "stuff". From my understanding, in a traditional `for` loop `i < 3; i++`, the `i` is evaluated, then incremented (output 0, 1, 2); in the second traditional, pre-increment test `i < 3; ++i`, `i` is incremented, then evaluated (hence the difference in output): "The [latter] increments the value of a variable and returns the resulting value; the [former] increments the value of the variable and returns the value prior to the increment." That difference in behaviour is significant and not irrelevant (there are tomes of work dedicated to... – Thomas Sep 26 '14 at 11:58
  • ... the significance of its importance and how the two affect the behaviour of the loop, e.g. whether the loop executes. The way I think about it (the way that I wrote it) is a bit different from the way the article I quoted understands it (the article presents a "truer" explanation). – Thomas Sep 26 '14 at 11:58
3

You just need to know that the statement int i = 0 is executed first , i.e , i takes first the value 0 , checks if the condition is true and then what the loop body is executed .

Then , i is incremented.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
George
  • 5,808
  • 15
  • 83
  • 160