The first case is a little more complicated because we are not seeing the value of `x , I can infer that it is 3.
Then it makes a preincrement and the value of x
turns 4. Then he does a post-description, so he takes the same value he already has and then subtracts 1 by doing x
value 3. At last, it fa a pre-decrement, taking the value 3 and changing to 2 which is the value used.
The second case in your explanation is wrong, would be:
6 * 6 + 20
36 + 20 = 56
Preincrement occurs. Then the value of i
which was 5 passes to 6, so it is this value that will be used. Then the same value 6 is used again. After it is used i
is worth 7, but since it is a post-increment this change will only occur after the value is already used.
When doing the pre the value is modified in the variable and then this new value is used where the variable is in the expression. When doing the post, the value of the variable is used in the place of the expression where it is, and after it has already been used the value of the variable is changed, so only in the next use of the variable will the value be seen to be changed.
But it’s very simple to solve all this in real code. Never use an operator that causes side effect together with other operators. Use them alone in a row or somewhere the result will be used directly without being part of a larger expression.
Some languages even ended up with these operators because people did these confusing things. Do so that never gives a headache:
i++;
metodo(++i);
array[i++];
Some people think you should only use the first one, the other two people don’t really understand what happens anymore. The first does not matter, will do what is expected in an easy way to understand.
Even this is not such a big problem, but it already creates some confusion:
x++ * 2
Note that the variable that mutated was used only once.
Therefore he used precedence, you did not use it. The non-use of precedence would be he, for example, to do the multiplication before doing the increment. He did this:
int y = ((((++x) * 5) / (x--)) + (--x));
Table of precedence with associativity:
Precedence only makes sense by looking in pairs, not the whole expression. It’s not that you look at everything and choose which one goes first, you have to go looking part by part. For example:
int y = ++x * 5 / x-- + --x;
The first operator we found is the assignment, the =
. It has low precedence, so you should look at everything on the left and right first to then use it. Not that this syntax works, but it would be more or less like this:
(int y) = (++x * 5 / x-- + --x);
He will end up staying last because of the very low precedence.
When the compiler establishes precedence and associativity in the background what he does is to put parentheses in the right places according to the established rules.
Moving on, now we have:
++ x * 5
What should he do first? The compiler takes the rules and determines that it will be so:
(++x) * 5
Now we have:
(++x) * 5 / x
Should he first do multiplication or division? Both operators have the same precedence. Associativity is left to right so first do multiplication:
((++x) * 5) / x
Continuing:
((++x) * 5) / x--
Now between the division and the post increment who wins is the second because he has greater precedence, is like this:
((++x) * 5) / (x--)
Continuing:
((++x) * 5) / (x--) + --x
Again the pre-deceit wins and gets:
((++x) * 5) / (x--) + (--x)
Now how to resolve between division and addition?
(((++x) * 5) / (x--)) + (--x)
The division takes precedence over the addition so it stayed that way.
Finally all this is in parentheses to apply with the =
that has the least precedence. Now it is easy to visualize, we solve everything from left to right just respecting the parentheses. Do the preincrement, then multiply that result with the literal 5, then divide that result with the post-decrement result (because it is in parentheses). then take all this result and add as the result of the preincrement.
If the language did not take precedence (I have already made such a language experimentally just to see how it looks) to give the same result you would have to put all these parentheses in hand.
In the case how x++ is above ++x in the precedence table I thought I would always do the post increment (or post-decrement) always first. So the precedence for these cases will always be left to right?
– Deivson Bezerra
Precedence is always between two operators when there is ambiguity of which must come first, does not affect the whole expression. Goes for everything, always looks at an operator with the next to decide which comes first, does not look at the others, then look at other 2, one of them may be that already solved before.
– Maniero
Please explain more about this table I couldn’t understand, leaving you with more questions rsrs int i = 5; int j = 5; System.out.println(j + 1 / i++ - i-); Output: -1 output: -1
– Deivson Bezerra
It shows when the operator should be read when he goes to disambiguate which one goes first, if he looks the way we’re used to from left to right, or the opposite. For example an allocation operator, this is important when operators have the same precedence.
– Maniero