Differences between x++ and x x

In the code many times I see x++ in loops, but I ever find myself ++x.

Is there any difference between these two expressions?

 51
Author: lois6b, 2015-12-03

7 answers

In the code many times I see x++ in loops, but I ever find myself ++x.

If you refer to constructions of this type:

public static void main(String[] args) {
    for (int i = 0; i < 10; ++i) {
        System.out.println(i);
    }
    for (int i = 0; i < 10; i++) {
        System.out.println(i);
    }
}

... so No there is difference. If we see the bytecode :

public static void main(java.lang.String[]);
  Code:
     0: iconst_0
     1: istore_1
     2: iload_1
     3: bipush        10
     5: if_icmpge     21
     8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
    11: iload_1
    12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
    15: iinc          1, 1
    18: goto          2
    21: iconst_0
    22: istore_1
    23: iload_1
    24: bipush        10
    26: if_icmpge     42
    29: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
    32: iload_1
    33: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
    36: iinc          1, 1
    39: goto          23
    42: return

In both cases, just after invoking the println ( invokevirtual #3 ), the variable 1 (in the code it is i for both cases) is incremented by 1. See the iinc 1, 1 before goto.


No however, if you mean something like this:

public static void main(String[] args) {
    for (int i = 0; i < 10;) {
        System.out.println(i++);
    }
    for (int i = 0; i < 10;) {
        System.out.println(++i);
    }
}

... so yes there is difference. Reviewing the bytecode :

public static void main(java.lang.String[]);
  Code:
     0: iconst_0
     1: istore_1
     2: iload_1
     3: bipush        10
     5: if_icmpge     21
     8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
    11: iload_1
    12: iinc          1, 1
    15: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
    18: goto          2
    21: iconst_0
    22: istore_1
    23: iload_1
    24: bipush        10
    26: if_icmpge     42
    29: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
    32: iinc          1, 1
    35: iload_1
    36: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
    39: goto          23
    42: return

In the first case, the value of variable 1 (i) is first loaded to be used in the println. See the iload_1. This variable is then increased by 1. See the iinc 1, 1.

In the second case, first the value of the variable 1 (i) is increased by 1, See the iinc 1, 1. Then it is loaded the value of the variable 1 (i) to be used in the println. See the iload_1.

 40
Author: Paul Vargas, 2015-12-04 21:00:24

POST INCREMENT:

x++, the value of the expression is the value of the variable before the new value is stored.

Example:

int x = 1;
System.out.println(x++); // imprime 1.
System.out.println(x);   // imprime 2.

PRE INCREMENT:

++x, the value of the expression is the value of the variable after the new value is stored.

Example:

int x = 1;
System.out.println(++x); // imprime 2. 
System.out.println(x);   // imprime 2.

Similar for x-- and --x

Examples:

int x = 1;
System.out.println(x--); // imprime 1. 
System.out.println(x);   // imprime 0.

int x = 1;
System.out.println(--x); // imprime 0. 
System.out.println(x);   // imprime 0.

More information:

 42
Author: Jorgesys, 2015-12-04 23:24:58

The difference is not in that the increment is executed before or after evaluating the expression but in the return value of the two expressions

According to the official Java specification in Section: 15.14.2. Postfix Increment Operator { and 15.15.1. Prefix Increment Operator {

15.14.2. Postfix Increment Operator {

...The value of the postfix increment expression is the value of the variable before the new value is stored.

Translation

15.14.2. Postfix increment operator {

The value of the postfix increment expression is the value of the variable before the new value is stored.

Also

15.15.1. Prefix Increment Operator {

The value of the prefix increment expression is the value of the variable after the new value is stored.

Translation

15.15.1. Prefix increment operator {

The value of the prefix increment expression is the value of the variable after the new value is stored.

Both increase the variable x by 1. The difference is that the expression ++x returns the value of the incremented variable Instead the expression x++ returns the original value of the variable before it is incremented.

I.e.:

int x = 5;
System.out.println(++x);  // Imprime 6, x vale 6: El resultado de la expresión ++x es 6 y se imprime 6
System.out.println(x); // Imprime 6, x vale 6: x ya se incrementó por lo que devuelve 6

While:

int x = 5;
System.out.println(x++);  // Imprime 5, x vale 6. La variable x ya es 6 pero el resultado de la expresión es 5 por lo que se imprime 5
System.out.println(x); // Imprime 6, x vale 6: x ya se incrementó por lo que devuelve 6
 19
Author: Carlos Muñoz, 2020-06-11 10:54:57

I know the question is tagged in Java, and I don't know the implementation in this language (although I guess it will be similar), but in C#, although the normal and intuitive thing is to say that "one returns the value before incrementing, and the other after", and that more or less gives the basic meaning... the reality is that the implementation is not so, and it has a very concrete sequence of events.

This is not a problem if we use it only: x++; does not bring any problems and simple explanation it's valid... but if we get into multi-threads, and long operations with different operator precedences, the thing changes.

As I say, I don't know how Java does it, but in C#, the sequence of each command is perfectly defined (and I imagine in Java it will be similar):

For the prefix type (++x), the sequence is:

  1. is evaluated x to produce the variable
  2. the value of the variable is copied to a temporary space
  3. to temporary variable is incremented and produces a new value (which does not overwrite the temporary)
  4. the new value is saved in the variable
  5. the new value is returned (not the variable)

For the suffix Type (x++), the sequence is:

  1. is evaluated x to produce the variable
  2. the value of the variable is copied to a temporary space
  3. the temporary variable is incremented and produces a new value (which does not overwrite the temporary)
  4. the new value is saved in the variable
  5. returns the value of the temporary copy

Therefore, the sequence of events occurs in both cases in the same order, and does not change either the evaluation or the increment of the variable, the only thing that changes is the value that is returned. There is only difference in Step 5.

In C# using method extensions, this is very easy to test... in Java I don't have it so clear (I only have notions Java basics).

Sorry for answering using C#, the question being tagged as Java, but as I said, I suspect the implementation should be similar, if not equal.

 5
Author: Jcl, 2015-12-03 17:52:57

Both increase the value of the variable by 1. If you use them in a line where the only expression is there is no difference, but if you execute them together with others there is an important variation.

  • X x does this before the expression is evaluated. It is also called PREINCREMENTO

    Example:

    int x = 5;
    System.out.println(++x); // escribira 6 porque ejecutará x + 1 ANTES de printar
    System.out.println(x);   // volverá a escribir 6!!!!
    
  • X hace does so after the expression is evaluated. It is also called POSTINCREMENTO

    Example:

    int x = 5;
    System.out.println(x++); // escribirá 5 porque ejecutará x + 1 DESPUÉS de printar
    System.out.println(x);   // escribirá 6
    

This type of expression is also very common when making allocations of an array when performing a loop without a counter (for example for-each) or filling several properties of the same object thus saving a line of code and gaining readability.

arrayALlenar[i++] = elemento;  

Instead of

arrayALlenar[i] = elemento;  
i++;
 4
Author: Jordi Castilla, 2015-12-03 17:04:54

++x increments the variable before it is called. X++ calls it and then increments it.

 4
Author: Emiliano, 2016-03-03 16:00:35

Both do the same thing except that the postincrement is evaluated at the value of the variable before the incremented value is stored and the preincrement is evaluated at the value of the variable after the incremented value is stored.

The pre and post increment are defined in the Java Language Specification (JLS) in two sections of which I reproduce translated parts that are significant to this question (emphasis mine) :

  • 15.14.2:Postfix increment operator {
    (..omit..)
    At runtime, if the evaluation of the expression completes abruptly, then the postfix increment expression completes abruptly for the same reason and there is no increment. Otherwise, the value 1 is added to the value of the variable and the sum is stored in the variable. (...omit...) The value of the postfix increment expression is the value of the variable before the new value is stored.
    (..omit..)

  • 15.15.1. Prefix increment operator {
    (..omit..)
    At runtime, if the evaluation of the expression completes abruptly, then the prefix decrement expression completes abruptly for the same reason and there is no increment. Otherwise, the value 1 is added to the value of the variable and the sum is stored in the variable. (...omit...) The value of the postfix increment expression is the value of the variable after the new value is stored.
    (..omit..)

Note that it is all the same, unless the value to which the expression is evaluated, which is the one that had the variable before that stored the new value increased to increase the postfix and is the value of the variable then is increased to increase prefix.

All of this has no significance in code like the following:

for ( int n=1; n<10; ++n)
for ( int n=1; n<10; n++)

In this code, for the same value of the n, the expressions ++n and n++ evaluate to different values, but this is irrelevant since this value is not used and the only thing that has significant effect is the fact that the variable is incremented to 1, which happens in both cases. Both loops will run the same number of iterations.

But it does matter in code like the following :

int a; int b;
a = 3;
b = a++;
System.out.println( "a="+a + " b=" + b);
a = 3;
b = ++a; 
System.out.println( "a="+a + " b=" + b);

Where the output is:

A=4 b = 3
a=4 b = 4

In the expression b = a++ is evaluated, the variable a (which is 3), we add 1 to this value and the result of the sum (4) is stored in the variable. The result of the expression a++ is the value of the variable a before that will store the new value (which was 3), so that the result of the expression a++ is 3. And this, 3, is what is stored in b.

In the expression b = ++a the variable a (which is worth 3) is evaluated, 1 is added to this value and the result of the sum (4) is stored in the variable a. The result of the expression ++a is the value that the variable has a after the new value (which is 4) is stored, the result of the expression ++a is 4. And this, 4, is what is stored in b.

Strictly following this way of evaluating the pre and postfix increment we can correctly evaluate any expression in which they are involved. For example:

    int a; int b;
    a = 3;
    b = ++a + a++;
    System.out.println( "a="+a + " b=" + b);
    a = 3;
    b = a++ + a++; 
    System.out.println( "a="+a + " b=" + b);

In the first expression b ends up being worth 8 because the first ++a evaluates to 4 (the value after storing the rise) and when you run the second a++ the variable a already contains 4, is increased to 5, but the value of the expression a++ is the variable before the increase, which evaluates to 4. And 4+4=8.
In the second expression b ends up being worth 7 because the first a++ evaluates to 3 (the value before storing the rise) and when you run the second a++ the variable a already contains 4, is increased to 5, but the value of the expression a++ is the variable before the increase with which evaluates to 4. And 3+4=7.

BUT IT'S BETTER NOT TO DO THAT

Although we understand perfectly how the pre and post increment operators work using them in expressions that do not be trivial will only serve to confuse. To you, to your co-workers, to your coordinator, to the one who reviews the code, to the one who has to deal with the Code 5 years later when the one who wrote it has long since left the company, to the cat...

 3
Author: Anonymous Coward, 2020-06-09 14:37:06