38

From the program below or here, why does the last call to System.out.println(i) print the value 7?

class PrePostDemo {
    public static void main(String[] args) {
        int i = 3;
        i++;

        System.out.println(i);    // "4"

        ++i;
        System.out.println(i);    // "5"
        System.out.println(++i);  // "6"
        System.out.println(i++);  // "6"
        System.out.println(i);    // "7"
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
O_O
  • 4,397
  • 18
  • 54
  • 69
  • 7
    I believe I somewhat understand where your misunderstanding comes from. You believe a new value will only be assigned to `i` when it's a statement on its own? When passing arguments to functions, the statements (in this case post and prefix) are executed before passing them. Add the behavioral difference between postfix and prefix as explained in the answers below, and you understand why you get that output. – Steven Jeuris Mar 24 '11 at 01:22
  • possible duplicate of [What is x after "x = x++"?](http://stackoverflow.com/questions/7911776/what-is-x-after-x-x) – nawfal Jul 20 '14 at 08:56
  • http://stackoverflow.com/a/30480534/4533771 – Dhanuka Jun 16 '15 at 02:00

11 Answers11

76
i = 5;
System.out.println(++i); //6

This prints out "6" because it takes i, adds one to it, and returns the value: 5+1=6. This is prefixing, adding to the number before using it in the operation.

i = 6;
System.out.println(i++); //6 (i = 7, prints 6)

This prints out "6" because it takes i, stores a copy, adds 1 to the variable, and then returns the copy. So you get the value that i was, but also increment it at the same time. Therefore you print out the old value but it gets incremented. The beauty of a postfix increment.

Then when you print out i, it shows the real value of i because it had been incremented: 7.

Timwi
  • 65,159
  • 33
  • 165
  • 230
Spidy
  • 39,723
  • 15
  • 65
  • 83
  • 3
    All other answers here say that the value of "i" will be used first and then it will be incremented but well as you said is correct that value gets incremented and then the COPY of old value is returned. We understand more when we take example of i = 5;i = i++; If the value was assigned first and incremented then i would be 6 but in this case is 5 – Saumyaraj Jul 15 '16 at 18:34
20

Another way to illustrate it is:

++i will give the result of the new i, i++ will give the result of the original i and store the new i for the next action.

A way to think of it is, doing something else within the expression. When you are printing the current value of i, it will depend upon whether i has been changed within the expression or after the expression.

int i = 1;
result i = ++i * 2 // result = 4, i = 2

i is evaluated (changed) before the result is calculated. Printing i for this expression, shows the changed value of i used for this expression.

result i = i++ * 2 // result = 2, i = 2

i is evaluated after the result in calculated. So printing i from this expression gives the original value of i used in this expression, but i is still changed for any further uses. So printing the value for i immediately after the expression, will show the new incremented value of i. As the value of i has changed, whether it is printed or used.

result i = i++ * 2 // result = 2, i = 2
System.out.println(i); // 2

If you kept a consistent pattern and included print lines for all the values:

int i = 3;
System.out.println(i);    //  3
System.out.println(i++);  //  3
System.out.println(i);    // "4"
System.out.println(++i);  //  5
System.out.println(i);    // "5"
System.out.println(++i);  // "6"
System.out.println(i++);  // "6"
System.out.println(i);    // "7"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
5

Think of ++i and i++ as similar to i = i+1. But it is not the same. The difference is when i gets the new increment.

In ++i , the increment happens immediately.

But if i++ is there, the increment will happen when the program goes to the next line.

Look at the code here.

int i = 0;
while(i < 10){
   System.out.println(i);
   i = increment(i);
}

private int increment(i){
   return i++;
}

This will result in a nonending loop. Because i will be returned with the original value and after the semicolon, i will get incremented, but the returned value has not been. Therefore i will never actually returned as an incremented value.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dilruk
  • 379
  • 5
  • 8
2
System.out.println(i++);  // "6"

This sends println the value I had prior to this line of code (6), and then increments I (to 7).

Dhanuka
  • 2,826
  • 5
  • 27
  • 38
Jumbogram
  • 2,249
  • 1
  • 20
  • 24
2

Why wouldn't the variable have been updated?

  • Postfix: passes the current value of i to the function and then increments it.
  • Prefix: increments the current value and then passes it to the function.

The lines where you don't do anything with i make no difference.

Notice that this is also true for assignments:

i = 0;
test = ++i;  // 1
test2 = i++; // 1
Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
1

An example of how the actual operators are implemented:

class Integer {
  private int __i;

  function Integer ++() { // Prefix operator i.e. ++x
    __i += 1; // Increment
    return this; // Return the object with the incremented value
  }

  function Integer ++(Integer x) { // Postfix operator, i.e., x++
    __i+=1; // Increment
    return x; // Return the original object
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
monkunashi
  • 41
  • 4
0

Well, think of it in terms of temporary variables.

i = 3;
i ++; // Is equivalent to:   temp = i++; and so, temp = 3 and then "i" will increment and become i = 4;
System.out.println(i); // Will print 4

Now,

i = 3;
System.out.println(i++);

is equivalent to

temp = i++;  // 'temp' will assume a value of the current "i", after which "i" will increment and become i = 4
System.out.println(temp); // We're printing 'temp' and not "i"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

Maybe you can understand better Prefix/postfix with this example.

public class TestPrefixPostFix
{
    public static void main (String[] args)
    {
        int x = 10;
        System.out.println((x++ % 2 == 0) ? "yes " + x: " no " + x);
        x = 10;
        System.out.println((++x % 2 == 0) ? "yes " + x: " no " + x);
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lanavia
  • 1
  • 1
0

This may be easy to understand:

package package02;

public class C11PostfixAndPrefix {

    public static void main(String[] args) {
        // In this program, we will use the value of x for understanding prefix 
        // and the value of y for understaning postfix. 
        // Let's see how it works. 
        
        int x = 5; 
        int y = 5; 
        
        Line 13:   System.out.println(++x);  // 6   This is prefixing. 1 is added before x is used. 
        Line 14:   System.out.println(y++);  // 5   This is postfixing. y is used first and 1 is added. 
        
        System.out.println("---------- just for differentiating");
        
        System.out.println(x);  // 6   In prefixing, the value is same as before {See line 13}
        System.out.println(y);  // 6   In postfixing, the value increases by 1  {See line 14} 
        
        // Conclusion: In prefixing (++x), the value of x gets increased first and the used 
        // in an operation. While, in postfixing (y++), the value is used first and changed by
        // adding the number. 
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

It prints 7 for the last statement, because in the statement above, its value is 6 and it's incremented to 7 when the last statement gets printed.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Guest
  • 9
  • 1
0

This might help... it also took my to understand this puzzle.

public class Main {
  public static void main(String[] args) {

    int x = 5;
    int y = 5;

    System.out.println(++x);
    System.out.println(y++);

    System.out.println("------");

    System.out.println(x);
    System.out.println(y);
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131