Programming languages have a lot of operators. More than most calculators anyway. Do you know what they are? Did you know there’s an order to them? This episode explains precedence, associativity, and evaluation order.
Let’s say you have this statement:
int i = 2 + 3 * 4 – 5;
The multiplication takes precedence over the addition and subtraction and goes first. The multiplication operator uses the symbol * and is a binary operator. This means it takes two operands. In this case, that is 3 and 4. After multiplying 3 by 4, it’s as if the statement now becomes:
int i = 2 + 12 – 5;
Both the addition and subtraction operators have the same precedence but they have left-to-right associativity which means that the addition is performed next. And then the subtraction.
If you want to change this order, you can use parenthesis. So if you wanted 2 to be added with 3 first, then you could write your code like this:
int i = (2 + 3) * 4 – 5;
You also have unary operators that require only a single operand like this pointer dereference:
int i = 5;
int * iPtr = &i;
int iCopy = *iPtr;
Notice how the same asterisk symbol is used to mean multiplication above, then used here to declare a pointer type and then used again to dereference the iPtr pointer and assign the value 5 to the iCopy variable. Many languages use symbols for different purposes and they really mean different things. The meaning will be clear form the usage. It has to be or the compiler won’t be able to understand your code.
You can also write the first example to use methods instead of integer values. Then it’ll look like this:
int i = methodA() + methodB() * methodC() – methodD();
Here, I’ve just replaced 2, 3, 4, and 5 with method calls. You already know that the multiplication will be done first before the addition or subtraction. But what order will the methods themselves be called? In other words, will the compiler choose to call methodB before or after calling methodC? It has to call both methods before it can perform the multiplication and that’s all you can rely on. The actual order is up to the compiler implementation and could change from one version of your compiler to the next.