You posed excellent questions. I had to play computer for a while to figure it out. Let me explain the concept of playing computer first. It is a technique that you will find handy in any
programming language to determine what the correct results of your code should produce. That is not to say that your code is correct. It just proves what the code should produce. This practice is used to confirm that the code is executing properly.
To play computer you break the instructions down to the simplest form, which is performing one operation at a time and tracking the values of all variables in each operation. Compound operations have to be broken down into their individual components and observe the proper precedence. This is easiest to do on paper.
Now for the explanations. You will find it helpful to refer to the table on page 77 of the book. The order of operations is from the top to the bottom: meaning the closer to the top the operator is listed, the more priority it has. The associativity in the far right column is just as important as the order.
- The * and \ operators are left associative and have the same priority according to the table. This means that 3/2*5 is evaluated from left to right. Using parentheses here is the equality 3/2*5=(3/2)*5. The 3/2 is performed first.
- The assignment operator (=) is right associative , and both = have the same priority according to the table. This means that x=y=5 will be evaluated from right to left. The value 5 will be assigned to y, and then the value of y will be assigned to x.
In all computations, anything in parentheses is evaluated first.
Now let's play computer with both of the statements you questioned.
k += (++k) + (++k) with k initialized to a value of 0
Referring to the table, we find that
- + is on the sixth level and is left associative
- += is on the sixteenth level and is right associative
Using the precedence rules we have to evaluate the expression in parentheses first, then the + operator, followed by the += operator in each of the individual steps of evaluating the entire line of code. It is important to notice that each time the value of k changes, every instance of k in the expression changes!
Ready? Here we go. Try following along on paper. It will make more sense.
k *= (++k) + (++k) with k initialized to 0
- The initial value of k is 0.
- Observing the right associativity of += has us start at the last (farthest to the right) expression (++k). The value of k is incremented by one; therefore, all instances of k now have a value of 1.
- Now we evaluate the first expression (++k). Remember that k now has a value of 1. The value of k is incremented by one again, giving it a value of 2. Now all instances of k in the expression have a value of 2.
- The expression now looks like this. k += 2 + 2 Because the expressions in parentheses have been evaluated, the table tells us that the + operator is the next in line. The result is k += 4. Once again the value of k has changed. The new value is 4.
- The expression k += 4 is Identical to k = k + 4. Because the new value of k is 4, we have the equivalent of k = 4 + 4. This results in k = 8.
I am going to abbreviate this soluton a little to avoid typographical errors. You can review the above solution if necessary for clarification.
Referring to the table again we find that the
- + operator is on the sixth level and is left associative
- *= operator is on the sixteenth level and is right associative
Our order of operations is parentheses, + operator, then the *= operator.
Here are the steps to evaluate:
- initial value of k is 0
- far right (++k) is evaluated first, giving k a value of 1 --> k = 1 everywhere
- left (++k) is evaluated next, giving k a value of 2 --> k = 2 everywhere
- now k *= 2 + 2 --> k *= 4, k = 2 * 4 --> k = 8
Does that make sense? If not tell me where it does not make sense and the value of k you have at that point. I'll try to walk you through it.