THIS:
This:
int i= 0; testArray[i++]= testArray[i++]+1;
*** "And after this code executes, i == 2"
The thing about statements such as this is the order of operations. [ ] has higher precedence than ++ , such that testArray[i++] means enter the array at index i, do whatever you came to do, then increment i. And even though it serves no purpose for what you are wanting to accomplish, after everything completes on the right side of the assignment, the last thing to happen is that i gets incremented "again" : )
where initially, i=0
testArray[i++] = testArray[i++]+1;
for the expression on the left hand side:
testArray[0] (which is the integer value 10), is where we enter the array (final result goes here!). Then, i gets incremented to 1
"equals"
for the expression on the right hand side:
using our newly incremented i variable....
testArray[1] (which is the integer value 20) is added to the literal integer value 1, and the result (which is 21) is then stored in testArray[0]. And finally the i in the right side expression gets incremented to 2.
Or, we could just say:
i=0; testArray[i] = testArray[i+1] + 1;
But honestly, where is the fun in that ?
Just for practice, code the same snippet using prefix notation on i and see what happens! Then read about "associativity" as it relates to order of operations.