From page 280 of OCP Java SE 6 Programmer Practice Exams, question 9:
int x = 3;
x = x++;
// x is still 3
In the explanation we can read that:
The x = x++; line doesn't leave x == 4 because the ++ is applied
after the assignment has occurred.
I agree that x is 3, I understand post-incremenation.
I don't agree with the explanation. I would replace "after" with "before".
I thought it works like this:
x is 3.
x++ is executed. I see this post-increment operator as a function:
int operator++() {
int temp = getX();
setX(temp + 1);
return temp;
}
So, after x++ execution, x is 4, but the value returned from x++ expression is 3.
Now, the assignment =. Simply write returned 3 to x.
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
...the ++ is applied after the assignment has occurred.
Okay, hold on. This is actually confusing and perhaps suggests an incorrect behavior.
You have the expression†:
x = ( x++ )
What happens is (JLS 15.26.1):
The expression on the left-hand side of the assignment x is evaluated (to produce a variable).
The expression on the right-hand side of the assignment ( x++ ) is evaluated (to produce a value).
The evaluation of the right-hand side is: x is post-incremented, and the result of the expression is the old value of x.
The variable on the left-hand side, x, is assigned the value produced by the evaluation of the right-hand side, which is the old value of x.
So the post-increment happens before the assignment.
(Therefore, as we know, the value of x after executing the statement x = x++; is the same as the value of x before executing the statement, which is 3.)
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
You are right.
Technically, the way it is specified is that x++ is evaluated before its result is stored and during the evaluation of the assignment operator. So x++ can be interpreted as happening either before or during the assignment. Not after, so the book appears to be wrong either way.
Just for the heck of it, we may also look at some bytecode:
/* int x = 3; */
iconst_3 // push the constant 3 on to the stack : temp = 3
istore_0 // pop the stack and store in local variable 0 : x = temp
/* x = x++; */
iload_0 // push local variable 0 on to the stack : temp = x
iinc 0 1 // increment local variable 0 by 1 : x = x + 1
istore_0 // pop the stack and store in local variable 0 : x = temp
The iinc happens before the istore.
†: The parentheses have no effect on the evaluation, they are just there for clarity.
Reaching over to the official spec:
postfix ++ section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
assignment operator section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1
In terms of assignment, this is simple assignment, so we hit case 3:
First, the left-hand operand is evaluated to produce a variable -- x
no errors -> the right-hand operand is evaluated -- x++
"the value of the right-hand operand is converted to the type of the left-hand variable, is subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable"
So in step 2, the postfix operator should get resolved, and then in step 3, x gets assigned its original value again:
call: x = x++;
interframe: LHS is variable 'x'
interframe: RHS caches return value as 3
interframe: x is incremented to 4
interframe: RHS cached value '3' is returned for assignment
interframe: variable x is assigned value 3
call result: x = 3
So I think you're right in that the book is wrong, and it might be worth contacting the authors or publisher to have a correction published (or added to an errata page, etc)
x++ means "use x and then increment x."
You can also use ++x, which means "increment x and then use x."
More easily, however, you can simply do
x += 1;
++x is called preincrement while x++ is called postincrement.
int x = 3;
x = ++x;
exemple
int x = 5, y = 5;
System.out.println(++x); // outputs 6
System.out.println(x); // outputs 6
System.out.println(y++); // outputs 5
System.out.println(y); // outputs 6
Related
I'm new to java.
Just found out that in the expression,
y=x++, y assumes the value of x and x becomes +1.
Forgive me if I sound stupid, but according to the order of precedence, assignment operators is at the end. So isn't x++ supposed to happen first followed by the assignment. Thanks in advance.
Q: So isn't x++ supposed to happen first followed by the assignment.
A: Yes. And that is what happens. The statement y = x++; is equivalent to the following:
temp = x; // | This is 'x++'
x = x + 1; // | (note that 'temp' contains the value of 'x++')
y = temp; // This is the assignment.
But as you see, the order of the operations (++ and =) doesn't affect what the operations actually do.
And therefore ...
Q: How are y=x++ and y=x-- different when the assignment operators has the least priority?
A: They aren't.
Operator precedence and evaluation order are two different concepts and they're not related.
If you have a() + b() * c(), that doesn't mean that b() and c() get invoked first because * has a higher precedence than +. a() still gets evaluated first. Evaluation order is typically left-to-right unless stated otherwise.
The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.
https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.7
y=x++ is assigning the value of x to y and then x gets incremented. The x++ operation is called a post-increment.
Here's some code that you can run for illustration:
int x = 0;
System.out.println("Illustration of post-increment");
System.out.println(x);
System.out.println(x++);
System.out.println(x);
int y = 0;
System.out.println("Illustration of pre-increment");
System.out.println(y);
System.out.println(++y);
System.out.println(y);
I was going through some exercises but I am confused in this one:
public static int f (int x, int y) {
int b=y--;
while (b>0) {
if (x%2!=0) {
--x;
y=y-2;
}
else {
x=x/2;
b=b-x-1;
}
}
return x+y;
}
What is the purpose of b=y--?
So, for example, x=5 and y=5
when we first go inside of while loop (while (b>0)) will b = 4 or 5? When I am running the code in my computer b is 5. And the return is 3. It is really unclear to me. Sorry if I am unclear in my question.
int b=y--; first assignes b=y and then decrements y (y--).
Also take a look at the prefix/postfix unary increment operator.
This example (taken from the linked page) demonstrates it:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
The difference between a post-increment/decrement and a pre-increment/decrement is in the evaluation of the expression.
The pre-increment and pre-decrement operators increment (or decrement) their operand by 1, and the value of the expression is the resulting incremented (or decremented) value. In contrast, the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation.
In other words:
int a = 5;
int b;
b = --a; // the value of the expression --a is a-1. b is now 4, as is a.
b = a--; // the value of the expression a-- is a. b is still 4, but a is 3.
Remember that a program must evaluate expressions to do everything. Everything is an expression, even just a casual mention of a variable. All of the following are expressions:
a
a-1
--a && ++a
System.out.println(a)
Of course, in the evaluation of expressions, operator precedence dictates the value of an expression just as the PEMDAS you learned in grade school. Some operators, such as increment/decrement, have side effects, which is of course great fun, and one of the reasons why functional programming was created.
I believe b would equal 5 entering the loop because
b=y--;
When the "--" is behind the variable it decrements it after the action.
It's poor coding, as it can confuse new programmers.
The function, assuming it is passing by value, like in the example above (as opposed to passing by reference) takes a copy of y, decrements it, and assigns it to b. It does not alter the argument passed to the function when it was called.
Post increment
x++;
x += 1;
Post decrement
x--;
x -=1;
Pre increment : ++x;
Pre decrement : --x;
According to the Head First Java:
Difference between x++ and ++x :
int x = 0; int z = ++x;
Produces: x is 1, x is 1
in x = 0; int z = x++;
Produces: x is 1, z is 0
What happens (behind the curtains) when this is executed?
int x = 7;
x = x++;
That is, when a variable is post incremented and assigned to itself in one statement? I compiled and executed this. x is still 7 even after the entire statement. In my book, it says that x is incremented!
x = x++;
is equivalent to
int tmp = x;
x++;
x = tmp;
x does get incremented. But you are assigning the old value of x back into itself.
x = x++;
x++ increments x and returns its old value.
x = assigns the old value back to itself.
So in the end, x gets assigned back to its initial value.
The statement:
x = x++;
is equivalent to:
tmp = x; // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
// happens after the value is captured.
x = tmp; // ... this is the effect of assignment operation which is
// (unfortunately) clobbering the incremented value.
In short, the statement has no effect.
The key points:
The value of a Postfix increment/decrement expression is the value of the operand before the increment/decrement takes place. (In the case of a Prefix form, the value is the value of the operand after the operation,)
the RHS of an assignment expression is completely evaluated (including any increments, decrements and/or other side-effects) before the value is assigned to the LHS.
Note that unlike C and C++, the order of evaluation of an expression in Java is totally specified and there is no room for platform-specific variation. Compilers are only allowed to reorder the operations if this does not change the result of executing the code from the perspective of the current thread. In this case, a compiler would be permitted to optimize away the entire statement because it can be proved that it is a no-op.
In case it is not already obvious:
"x = x++;" is almost certainly a mistake in any program.
The OP (for the original question!) probably meant "x++;" rather than "x = x++;".
Statements that combine auto inc/decrement and assignment on the same variable are hard to understand, and therefore should be avoided irrespective of their correctness. There is simply no need to write code like that.
Hopefully, code checkers like FindBugs and PMD will flag code like this as suspicious.
int x = 7;
x = x++;
It has undefined behaviour in C and for Java see this answer. It depends on compiler what happens.
A construct like x = x++; indicates you're probably misunderstanding what the ++ operator does:
// original code
int x = 7;
x = x++;
Let's rewrite this to do the same thing, based on removing the ++ operator:
// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7
Now, let's rewrite it to do (what I think) you wanted:
// original code
int x = 7;
x++;
The subtlety here is that the ++ operator modifies the variable x, unlike an expression such as x + x, which would evaluate to an int value but leave the variable x itself unchanged. Consider a construct like the venerable for loop:
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
Notice the i++ in there? It's the same operator. We could rewrite this for loop like this and it would behave the same:
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
I also recommend against using the ++ operator in larger expressions in most cases. Because of the subtlety of when it modifies the original variable in pre- versus post-increment (++x and x++, respectively), it is very easy to introduce subtle bugs that are difficult to track down.
According to Byte code obtained from the class files,
Both assignments increment x, but difference is the timing of when the value is pushed onto the stack
In Case1, Push occurs (and then later assigned) before the increment (essentially meaning your increment does nothing)
In Case2, Increment occurs first (making it 8) and then pushed onto the stack(and then assigned to x)
Case 1:
int x=7;
x=x++;
Byte Code:
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iload_1 [x] //Push 7 onto stack
4 iinc 1 1 [x] //Increment x by 1 (x=8)
7 istore_1 [x] //Pop 7 and store in x
8 return //x now has 7
Case 2:
int x=7;
x=++x;
Byte Code
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iinc 1 1 [x] //Increment x by 1 (x=8)
6 iload_1 [x] //Push x onto stack
7 istore_1 [x] //Pop 8 and store in x
8 return //x now has 8
Stack here refers to Operand Stack, local: x index: 1 type: int
Post Increment operator works as follows:
Store previous value of operand.
Increment the value of the operand.
Return the previous value of the operand.
So the statement
int x = 7;
x = x++;
would be evaluated as follows:
x is initialized with value 7
post increment operator stores previous value of x i.e. 7 to return.
Increments the x, so now x is 8
Returns the previous value of x i.e. 7 and it is assigned back to x, so x again becomes 7
So x is indeed increased but since x++ is assigning result back to x so value of x is overridden to its previous value.
It's incremented after "x = x++;". It would be 8 if you did "x = ++x;".
The incrementing occurs after x is called, so x still equals 7. ++x would equal 8 when x is called
When you re-assign the value for x it is still 7. Try x = ++x and you will get 8 else do
x++; // don't re-assign, just increment
System.out.println(x); // prints 8
because x++ increments the value AFTER assigning it to the variable.
so on and during the execution of this line:
x++;
the varialbe x will still have the original value (7), but using x again on another line, such as
System.out.println(x + "");
will give you 8.
if you want to use an incremented value of x on your assignment statement, use
++x;
This will increment x by 1, THEN assign that value to the variable x.
[Edit]
instead of x = x++, it's just x++; the former assigns the original value of x to itself, so it actually does nothing on that line.
What happens when int x = 7; x = x++;?
ans -> x++ means first use value of x for expression and then increase it by 1.
This is what happens in your case. The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1.
Similarly ++x means -> increase the value of x first by one and then use in expression .
So in your case if you do x = ++x ; // where x = 7
you will get value of 8.
For more clarity try to find out how many printf statement will execute the following code
while(i++ <5)
printf("%d" , ++i); // This might clear your concept upto great extend
++x is pre-increment -> x is incremented before being used
x++ is post-increment -> x is incremented after being used
int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
So this means:
x++ is not equal to x = x+1
because:
int x = 7; x = x++;
x is 7
int x = 7; x = x = x+1;
x is 8
and now it seems a bit strange:
int x = 7; x = x+=1;
x is 8
very compiler dependent!
Most simplest explanation!
This is because ++ after the operand makes post increment it, means first the value got assigned to the variable & then incremented. While if you're expecting x value to be 8 then you should pre increment it like the way mentioned below:
x = x++;
This is the post-increment operator. It should be understood as "Use the operand's value and then increment the operand".
If you want the reverse to happen i.e "Increment the operand and then use the operand's value", you must use the pre-increment operator as shown below.
x = ++x;
This operator first increments the value of x by 1 and then assigns the value back to x.
I think this controversy can be resolved without going into code & just thinking.
Consider i++ & ++i as functions, say Func1 & Func2.
Now i=7;
Func1(i++) returns 7, Func2(++i) returns 8 (everybody knows this). Internally both the functions increment i to 8 , but they return different values.
So i = i++ calls the function Func1. Inside the function i increments to 8, but on completion the function returns 7.
So ultimately 7 gets allocated to i. (So in the end, i = 7)
This is because you used a post-increment operator.
In this following line of code
x = x++;
What happens is that, you're assigning the value of x to x. x++ increments x after the value of x is assigned to x. That is how post-increment operators work. They work after a statement has been executed. So in your code, x is returned first after then it is afterwards incremented.
If you did
x = ++x;
The answer would be 8 because you used the pre-increment operator. This increments the value first before returning the value of x.
What happens (behind the curtains) when this is executed?
int x = 7;
x = x++;
That is, when a variable is post incremented and assigned to itself in one statement? I compiled and executed this. x is still 7 even after the entire statement. In my book, it says that x is incremented!
x = x++;
is equivalent to
int tmp = x;
x++;
x = tmp;
x does get incremented. But you are assigning the old value of x back into itself.
x = x++;
x++ increments x and returns its old value.
x = assigns the old value back to itself.
So in the end, x gets assigned back to its initial value.
The statement:
x = x++;
is equivalent to:
tmp = x; // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
// happens after the value is captured.
x = tmp; // ... this is the effect of assignment operation which is
// (unfortunately) clobbering the incremented value.
In short, the statement has no effect.
The key points:
The value of a Postfix increment/decrement expression is the value of the operand before the increment/decrement takes place. (In the case of a Prefix form, the value is the value of the operand after the operation,)
the RHS of an assignment expression is completely evaluated (including any increments, decrements and/or other side-effects) before the value is assigned to the LHS.
Note that unlike C and C++, the order of evaluation of an expression in Java is totally specified and there is no room for platform-specific variation. Compilers are only allowed to reorder the operations if this does not change the result of executing the code from the perspective of the current thread. In this case, a compiler would be permitted to optimize away the entire statement because it can be proved that it is a no-op.
In case it is not already obvious:
"x = x++;" is almost certainly a mistake in any program.
The OP (for the original question!) probably meant "x++;" rather than "x = x++;".
Statements that combine auto inc/decrement and assignment on the same variable are hard to understand, and therefore should be avoided irrespective of their correctness. There is simply no need to write code like that.
Hopefully, code checkers like FindBugs and PMD will flag code like this as suspicious.
int x = 7;
x = x++;
It has undefined behaviour in C and for Java see this answer. It depends on compiler what happens.
A construct like x = x++; indicates you're probably misunderstanding what the ++ operator does:
// original code
int x = 7;
x = x++;
Let's rewrite this to do the same thing, based on removing the ++ operator:
// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7
Now, let's rewrite it to do (what I think) you wanted:
// original code
int x = 7;
x++;
The subtlety here is that the ++ operator modifies the variable x, unlike an expression such as x + x, which would evaluate to an int value but leave the variable x itself unchanged. Consider a construct like the venerable for loop:
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
Notice the i++ in there? It's the same operator. We could rewrite this for loop like this and it would behave the same:
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
I also recommend against using the ++ operator in larger expressions in most cases. Because of the subtlety of when it modifies the original variable in pre- versus post-increment (++x and x++, respectively), it is very easy to introduce subtle bugs that are difficult to track down.
According to Byte code obtained from the class files,
Both assignments increment x, but difference is the timing of when the value is pushed onto the stack
In Case1, Push occurs (and then later assigned) before the increment (essentially meaning your increment does nothing)
In Case2, Increment occurs first (making it 8) and then pushed onto the stack(and then assigned to x)
Case 1:
int x=7;
x=x++;
Byte Code:
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iload_1 [x] //Push 7 onto stack
4 iinc 1 1 [x] //Increment x by 1 (x=8)
7 istore_1 [x] //Pop 7 and store in x
8 return //x now has 7
Case 2:
int x=7;
x=++x;
Byte Code
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iinc 1 1 [x] //Increment x by 1 (x=8)
6 iload_1 [x] //Push x onto stack
7 istore_1 [x] //Pop 8 and store in x
8 return //x now has 8
Stack here refers to Operand Stack, local: x index: 1 type: int
Post Increment operator works as follows:
Store previous value of operand.
Increment the value of the operand.
Return the previous value of the operand.
So the statement
int x = 7;
x = x++;
would be evaluated as follows:
x is initialized with value 7
post increment operator stores previous value of x i.e. 7 to return.
Increments the x, so now x is 8
Returns the previous value of x i.e. 7 and it is assigned back to x, so x again becomes 7
So x is indeed increased but since x++ is assigning result back to x so value of x is overridden to its previous value.
It's incremented after "x = x++;". It would be 8 if you did "x = ++x;".
The incrementing occurs after x is called, so x still equals 7. ++x would equal 8 when x is called
When you re-assign the value for x it is still 7. Try x = ++x and you will get 8 else do
x++; // don't re-assign, just increment
System.out.println(x); // prints 8
because x++ increments the value AFTER assigning it to the variable.
so on and during the execution of this line:
x++;
the varialbe x will still have the original value (7), but using x again on another line, such as
System.out.println(x + "");
will give you 8.
if you want to use an incremented value of x on your assignment statement, use
++x;
This will increment x by 1, THEN assign that value to the variable x.
[Edit]
instead of x = x++, it's just x++; the former assigns the original value of x to itself, so it actually does nothing on that line.
What happens when int x = 7; x = x++;?
ans -> x++ means first use value of x for expression and then increase it by 1.
This is what happens in your case. The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1.
Similarly ++x means -> increase the value of x first by one and then use in expression .
So in your case if you do x = ++x ; // where x = 7
you will get value of 8.
For more clarity try to find out how many printf statement will execute the following code
while(i++ <5)
printf("%d" , ++i); // This might clear your concept upto great extend
++x is pre-increment -> x is incremented before being used
x++ is post-increment -> x is incremented after being used
int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
So this means:
x++ is not equal to x = x+1
because:
int x = 7; x = x++;
x is 7
int x = 7; x = x = x+1;
x is 8
and now it seems a bit strange:
int x = 7; x = x+=1;
x is 8
very compiler dependent!
Most simplest explanation!
This is because ++ after the operand makes post increment it, means first the value got assigned to the variable & then incremented. While if you're expecting x value to be 8 then you should pre increment it like the way mentioned below:
x = x++;
This is the post-increment operator. It should be understood as "Use the operand's value and then increment the operand".
If you want the reverse to happen i.e "Increment the operand and then use the operand's value", you must use the pre-increment operator as shown below.
x = ++x;
This operator first increments the value of x by 1 and then assigns the value back to x.
I think this controversy can be resolved without going into code & just thinking.
Consider i++ & ++i as functions, say Func1 & Func2.
Now i=7;
Func1(i++) returns 7, Func2(++i) returns 8 (everybody knows this). Internally both the functions increment i to 8 , but they return different values.
So i = i++ calls the function Func1. Inside the function i increments to 8, but on completion the function returns 7.
So ultimately 7 gets allocated to i. (So in the end, i = 7)
This is because you used a post-increment operator.
In this following line of code
x = x++;
What happens is that, you're assigning the value of x to x. x++ increments x after the value of x is assigned to x. That is how post-increment operators work. They work after a statement has been executed. So in your code, x is returned first after then it is afterwards incremented.
If you did
x = ++x;
The answer would be 8 because you used the pre-increment operator. This increments the value first before returning the value of x.
What happens (behind the curtains) when this is executed?
int x = 7;
x = x++;
That is, when a variable is post incremented and assigned to itself in one statement? I compiled and executed this. x is still 7 even after the entire statement. In my book, it says that x is incremented!
x = x++;
is equivalent to
int tmp = x;
x++;
x = tmp;
x does get incremented. But you are assigning the old value of x back into itself.
x = x++;
x++ increments x and returns its old value.
x = assigns the old value back to itself.
So in the end, x gets assigned back to its initial value.
The statement:
x = x++;
is equivalent to:
tmp = x; // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
// happens after the value is captured.
x = tmp; // ... this is the effect of assignment operation which is
// (unfortunately) clobbering the incremented value.
In short, the statement has no effect.
The key points:
The value of a Postfix increment/decrement expression is the value of the operand before the increment/decrement takes place. (In the case of a Prefix form, the value is the value of the operand after the operation,)
the RHS of an assignment expression is completely evaluated (including any increments, decrements and/or other side-effects) before the value is assigned to the LHS.
Note that unlike C and C++, the order of evaluation of an expression in Java is totally specified and there is no room for platform-specific variation. Compilers are only allowed to reorder the operations if this does not change the result of executing the code from the perspective of the current thread. In this case, a compiler would be permitted to optimize away the entire statement because it can be proved that it is a no-op.
In case it is not already obvious:
"x = x++;" is almost certainly a mistake in any program.
The OP (for the original question!) probably meant "x++;" rather than "x = x++;".
Statements that combine auto inc/decrement and assignment on the same variable are hard to understand, and therefore should be avoided irrespective of their correctness. There is simply no need to write code like that.
Hopefully, code checkers like FindBugs and PMD will flag code like this as suspicious.
int x = 7;
x = x++;
It has undefined behaviour in C and for Java see this answer. It depends on compiler what happens.
A construct like x = x++; indicates you're probably misunderstanding what the ++ operator does:
// original code
int x = 7;
x = x++;
Let's rewrite this to do the same thing, based on removing the ++ operator:
// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7
Now, let's rewrite it to do (what I think) you wanted:
// original code
int x = 7;
x++;
The subtlety here is that the ++ operator modifies the variable x, unlike an expression such as x + x, which would evaluate to an int value but leave the variable x itself unchanged. Consider a construct like the venerable for loop:
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
Notice the i++ in there? It's the same operator. We could rewrite this for loop like this and it would behave the same:
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
I also recommend against using the ++ operator in larger expressions in most cases. Because of the subtlety of when it modifies the original variable in pre- versus post-increment (++x and x++, respectively), it is very easy to introduce subtle bugs that are difficult to track down.
According to Byte code obtained from the class files,
Both assignments increment x, but difference is the timing of when the value is pushed onto the stack
In Case1, Push occurs (and then later assigned) before the increment (essentially meaning your increment does nothing)
In Case2, Increment occurs first (making it 8) and then pushed onto the stack(and then assigned to x)
Case 1:
int x=7;
x=x++;
Byte Code:
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iload_1 [x] //Push 7 onto stack
4 iinc 1 1 [x] //Increment x by 1 (x=8)
7 istore_1 [x] //Pop 7 and store in x
8 return //x now has 7
Case 2:
int x=7;
x=++x;
Byte Code
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iinc 1 1 [x] //Increment x by 1 (x=8)
6 iload_1 [x] //Push x onto stack
7 istore_1 [x] //Pop 8 and store in x
8 return //x now has 8
Stack here refers to Operand Stack, local: x index: 1 type: int
Post Increment operator works as follows:
Store previous value of operand.
Increment the value of the operand.
Return the previous value of the operand.
So the statement
int x = 7;
x = x++;
would be evaluated as follows:
x is initialized with value 7
post increment operator stores previous value of x i.e. 7 to return.
Increments the x, so now x is 8
Returns the previous value of x i.e. 7 and it is assigned back to x, so x again becomes 7
So x is indeed increased but since x++ is assigning result back to x so value of x is overridden to its previous value.
It's incremented after "x = x++;". It would be 8 if you did "x = ++x;".
The incrementing occurs after x is called, so x still equals 7. ++x would equal 8 when x is called
When you re-assign the value for x it is still 7. Try x = ++x and you will get 8 else do
x++; // don't re-assign, just increment
System.out.println(x); // prints 8
because x++ increments the value AFTER assigning it to the variable.
so on and during the execution of this line:
x++;
the varialbe x will still have the original value (7), but using x again on another line, such as
System.out.println(x + "");
will give you 8.
if you want to use an incremented value of x on your assignment statement, use
++x;
This will increment x by 1, THEN assign that value to the variable x.
[Edit]
instead of x = x++, it's just x++; the former assigns the original value of x to itself, so it actually does nothing on that line.
What happens when int x = 7; x = x++;?
ans -> x++ means first use value of x for expression and then increase it by 1.
This is what happens in your case. The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1.
Similarly ++x means -> increase the value of x first by one and then use in expression .
So in your case if you do x = ++x ; // where x = 7
you will get value of 8.
For more clarity try to find out how many printf statement will execute the following code
while(i++ <5)
printf("%d" , ++i); // This might clear your concept upto great extend
++x is pre-increment -> x is incremented before being used
x++ is post-increment -> x is incremented after being used
int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
So this means:
x++ is not equal to x = x+1
because:
int x = 7; x = x++;
x is 7
int x = 7; x = x = x+1;
x is 8
and now it seems a bit strange:
int x = 7; x = x+=1;
x is 8
very compiler dependent!
Most simplest explanation!
This is because ++ after the operand makes post increment it, means first the value got assigned to the variable & then incremented. While if you're expecting x value to be 8 then you should pre increment it like the way mentioned below:
x = x++;
This is the post-increment operator. It should be understood as "Use the operand's value and then increment the operand".
If you want the reverse to happen i.e "Increment the operand and then use the operand's value", you must use the pre-increment operator as shown below.
x = ++x;
This operator first increments the value of x by 1 and then assigns the value back to x.
I think this controversy can be resolved without going into code & just thinking.
Consider i++ & ++i as functions, say Func1 & Func2.
Now i=7;
Func1(i++) returns 7, Func2(++i) returns 8 (everybody knows this). Internally both the functions increment i to 8 , but they return different values.
So i = i++ calls the function Func1. Inside the function i increments to 8, but on completion the function returns 7.
So ultimately 7 gets allocated to i. (So in the end, i = 7)
This is because you used a post-increment operator.
In this following line of code
x = x++;
What happens is that, you're assigning the value of x to x. x++ increments x after the value of x is assigned to x. That is how post-increment operators work. They work after a statement has been executed. So in your code, x is returned first after then it is afterwards incremented.
If you did
x = ++x;
The answer would be 8 because you used the pre-increment operator. This increments the value first before returning the value of x.