In the code I see many times x++
in loops, but sometimes I find ++x
.
Is there a difference between these two expressions?
In the code I see many times x++
in loops, but sometimes I find ++x
.
Is there a difference between these two expressions?
POST INCREMENT :
Example:
PRE-INCREASE :
Example:
Similar for
x--
and--x
Examples:
More information:
If you mean constructions of this type:
...then there is no difference. If we see the bytecode :
In both cases, just after calling the
println
(invokevirtual #3
), the variable 1 (in the code it is for both cases) is incrementedi
by 1. Seeiinc 1, 1
before thegoto
.However, if you mean something like this:
... then there is a difference. Checking the bytecode :
In the first case, the value of the variable 1 (
i
) is loaded first to be used in theprintln
. See theiload_1
. This variable is then incremented by 1. See theiinc 1, 1
.In the second case, the value of the variable 1 (
i
) is first increased by 1, Seeiinc 1, 1
. Then the value of the variable 1 (i
) is loaded to be used in theprintln
. See theiload_1
.The difference is not in whether the increment is executed before or after the expression is evaluated, 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 ++
Translation
Equally
Translation
Both increment the variable
x
by 1. The difference is that the expression++x
returns the value of the incremented variable, while the expressionx++
returns the original value of the variable before being incremented.Namely:
While:
I know that the question is tagged in Java, and I don't know the implementation in this language (although I suppose it will be similar), but in C#, although it is normal and intuitive 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 like that, and it has a very concrete sequence of events.
This is not a problem if we use it alone:
x++;
it does not bring any problem and the simple explanation is valid... but if we get into multithreading, and long operations with different operator precedences, things change.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 that in Java it will be similar):
For the prefix type (
++x
), the sequence is:x
to produce the variableFor the suffix type (
x++
), the sequence is:x
to produce the variableTherefore, the sequence of events occurs in both cases in the same order, and neither the evaluation nor the increment of the variable changes, 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'm not so clear (I only have basic notions of Java).
Sorry for answering using C#, with the question tagged as Java, but as I said, I suspect the implementation should be similar, if not the same.
Both increment the value of the variable by
1
. If you use them in a line where it is the only expression there is no difference, but if you execute them together with others there is an important variation.++x does this before the expression is evaluated. It's also called
PREINCREMENTO
Example:
x++ does this after the expression is evaluated. It's also called
POSTINCREMENTO
Example:
This type of expression is also very common when making assignments from an array when you perform a loop without a counter (for example for-each) or by filling in various properties of the same object, thus saving a line of code and gaining readability.
instead of
++x
increments the variable before it is called.X++
calls it and then increments it.They both do the same thing except that the post-increment evaluates to the value of the variable BEFORE the incremented value is stored and the pre-increment evaluates to 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 the parts that are significant for this question (emphasis mine):
15.14.2:Postfix Increment Operator ++
(..omitted..)
At run time, 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. (...omitted...) The value of the postfix increment expression is the value of the variable before the new value is stored.
(..omitted..)
15.15.1. Prefix Increment Operator ++
(..omitted..)
At run time, 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. (...omitted...) The value of the postfix increment expression is the value of the variable after the new value is stored.
(..omitted..)
Note that everything is the same, except for the value with which the expression is evaluated, which is the value that the variable had before the new value increased for the postfix increment was stored and is the value that the variable has after it is increased for the prefix increment.
All this has no importance in code like the following:
In that code, for the same value of
n
, the expressions++n
andn++
are evaluated to different values, but this is irrelevant since this value is not used and the only thing that has a significant effect is the fact that the variable is increased by 1, which It happens in both cases. Both loops will execute the same number of iterations.But it is important in code like the following:
Where the output is:
In the expression
b = a++
, the variablea
(which is equal to 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 expressiona++
is the value that the variable hasa
before the new value (which was 3) is stored in it, so the result of the expressiona++
is 3. And this, 3, is what is stored inb
.In the expression
b = ++a
, the variablea
(which is equal to 3) is evaluated, 1 is added to this value and the result of the sum (4) is stored in the variablea
. The result of the expression++a
is the value that the variable hasa
after the new value (which is 4) is stored in it, so the result of the expression++a
is 4. And this, 4, is what is stored inb
.By strictly following this way of evaluating prefix and postfix increment we can correctly evaluate any expression they are involved in. For example :
In the first expression
b
it ends up being 8 because the first++a
one evaluates to 4 (the value after storing the increment) and by the time the second one is executed,a++
the variablea
already contains 4, it is increased to 5 but the value of the expressiona++
is that of the variable before incrementing, thus evaluating to 4. And 4+4=8.In the second expression
b
it ends up being 7 because the firsta++
one evaluates to 3 (the value before storing the increment) and by the time the second one is executed,a++
the variablea
already contains 4, it is increased to 5 but the value of the expressiona++
is that of the variable before being incremented so it evaluates to 4. And 3+4=7.BUT IT'S BETTER NOT TO DO THAT
Although we fully understand how the pre and post increment operators work, using them in non-trivial expressions will only serve to confuse. To you, to your cooperators, 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...