Computer scienceProgramming languagesC++Operators and expressions

Operator precedence and associativity rules

8 minutes read

C++ uses different operators to create expressions that can operate on variables and constants. It is crucial to understand the order of evaluation of operators in an expression as it can significantly impact the final result. This is where operator precedence and associativity rules come into the picture. Operator precedence determines the order in which operators are evaluated, while associativity rules determine the order for operators of the same precedence.

Operators

You can categorize operators into different categories based on their behavior and the number of operands they work with. Let's dive into the world of operators, starting with the division of operators into unary, binary, and ternary.

1. Unary operators: Unary operators work with a single operand and modify its value or state. These operators come in different forms, each with a specific purpose. Let's see some common unary operators that you'll be using:

The unary plus operator (+) represents a positive value, although it usually has no practical effect. On the other hand, the unary minus operator (-) negates the value of an operand. For example:

int positive = +15; // positive remains 15
int negative = -15; // negative becomes -15

The increment (++) and decrement (--) operators increase or decrease the value of the operand by 1, respectively. You can use them in a prefix or postfix manner, affecting the value differently. For example:

#include <iostream>

int main() {
    int firstNum = 15;
    int secondNum = ++firstNum; // secondNum is 6, firstNum is 16
    int thirdNum = firstNum--; // thirdNum is 16, firstNum becomes 15

    std::cout << firstNum << std::endl; // 15
    std::cout << secondNum << std::endl; // 16
    std::cout << thirdNum << std::endl; // 16
    std::cout << firstNum << std::endl; // 15
}

2. Binary Operators: Binary operators are the most common in C++, as they operate on two operands. They perform various arithmetic, logical, and comparison operations. Perhaps the most used binary operators are the subtraction operator and the addition operator.

The arithmetic operators (+, -, /, %) perform basic arithmetic operations like addition, subtraction, multiplication, division, modulus (remainder), and the assignment operator (=) is used to assign a value to a variable. For example:

int num = 5;            // num is assigned the value of 5
int sum = num + 3;      // sum is 8
int difference = 7 - 2; // difference is 5
int product = 4 * 6;   // product is 24
int quotient = 10 / 3; // quotient is 3 (integer division)
int remainder = 10 % 3; // remainder is 1

3. Ternary Operator: The ternary operator is unique as it's the only operator that operates on three operands. It's often used for decision-making in a compact form. Let's take an example:

int x = 10, y = 5;
int max = (x > y) ? x : y; // max becomes 10

In this example, (x > y) ? x : y, (x > y) evaluates to true, so the value of x is assigned to max.

It's not important to understand the working of all the above operators and their explanations for now. These operators are discussed in detail in subsequent topics

Operator precedence

Imagine expressions as mathematical equations, just like those you learned in school. To ensure that C++ understands how to evaluate the above expressions correctly, use something similar to the BDMAS approach you might have encountered earlier. The term "BDMAS" stands for Brackets, Division, Multiplication, Addition, and Subtraction. This acronym guides you on how to prioritize operations when you have multiple operations in an expression.

  1. Brackets (): Just like in math, parentheses in C++ take precedence over everything else. So, whatever is inside the parentheses gets evaluated first. If there are nested parentheses, the innermost ones are evaluated before moving outward.

  2. Division / Multiplication: After handling the brackets, we move on to division and multiplication. These operations are done from left to right. So, if you have 4 / 2 * 3, you would first divide 4 by 2 to get 2, and then multiply 2 by 3 to get 6.

  3. Addition / Subtraction: Next in line are addition and subtraction. Just like division and multiplication, these are also carried out from left to right. For example, 5 + 2 - 1 would be calculated as 6.

In C++, operator precedence determines the order in which operators are evaluated in an expression. Operators with higher precedence are evaluated first, followed by operators with lower precedence, as you studied in the above paragraph. This helps in maintaining the correct outcome of the expression.

For example, consider the following expression:

int result = 6 + 2 * 4; // What will be the value of 'result'?

In this case, the multiplication operator (*) has higher precedence than the addition operator (+). Thus, 2 * 4 will be evaluated first, resulting in 8, and then the addition 6 + 8, which gives 14. So, the value of result will be 14.

Let's take another example:

int result = 15 / 3 - 3 % 6; // What will be the value of 'result'?

In this case, the division operator( / ) has higher precedence than all the operators. Thus, 15 / 3 is evaluated first, resulting in 5. Then, modulo operator(%) has higher precedence than the subtraction operator(-). Thus, 3 % 6 is evaluated, resulting in 3. Finally, the subtraction of 5 - 3, resulting in 2. So, the value of the result will be 2.

But how do you know that the multiplication operator has a higher precedence than the addition operator and division operator has a higher precedence than the modulo operator, and so on? Well, the precedence of operators is defined by the language specification. The C++ standard (ISO/IEC 14882) provides a clear and unambiguous set of rules that dictate the precedence of all operators.

Reference table: Let's take a look at some common operators and their precedence. Don't fret by looking at so many operators. You'll get used to some of the essential operators while working with C++.

Precedence table of operators

Associativity rules

Associativity rules come into play when multiple operators of the same precedence appear in an expression. Associativity can be left-to-right or right-to-left. For example, the addition operator(+) and subtraction operator(-) is left-associative, which means expressions are evaluated from left to right.

Consider the following expression:

int result = 12 / 6 * 3; // What will be the value of 'result'?

Now, there are two operators, that is, division and multiplication operators in the above example. So, why the compiler does not get confused about what to calculate first? Multiplication or Division? There comes the rule of associativity. When two operators have the same precedence (as in the above example), their associativity is implemented. Because division and multiplication operators are associative (left to right), the operator written on the left is evaluated first. As a result, in the above example, division occurs before multiplication. Thus 12 / 6 is evaluated first, resulting in 2. Then 2 * 3 is evaluated, resulting in 6.

Let's take another example:

#include <iostream>
using namespace std;

int main() {
    int x = 11, y = 6, z = 3;
    int result;

    result = x - y - z;
    cout << "Result with left-associative: " << result << endl;

    result = x = y = z;
    cout << "Result with right-associative: " << result << endl;

    return 0;
}

Here is the output of the above code snippet:

Result with left-associative: 2
Result with right-associative: 3

The subtraction operator (-) is left-associative. In the expression x - y - z, the subtraction is evaluated from left to right. So, the evaluation order is x - y, which results in 5, and then 5 - z, resulting in 2. The value of result will be 2.

The assignment operator (=) is right-associative. In the expression x = y = z, the assignment is evaluated from right to left. So, the evaluation order is y = z, which sets the value of y to 3, and then x = 3, which sets the value of x to 3. The value of result will be 3.

In C++, most of the operators exhibit left-to-right associativity, meaning that expressions with the same precedence are evaluated from left to right. However, there is one operator in C++ that has right-to-left associativity, and that is the assignment operator (=). However, there are some exceptions which you'll study later.

Reference table: Let's take a look at the associativity of the operators in the below table.

Associativity table of operators

Grouping operations with parentheses

Parentheses are used to group expressions and override the default precedence and associativity rules. Expressions inside parentheses are evaluated first before the outer expression. This allows you to control the order of evaluation explicitly.

Consider the following expression:

int result = 2 * (3 + 4); // What will be the value of 'result'?

In the above expression, the expression inside the parentheses (3 + 4) is evaluated first, resulting in 7, and then 2 * 7, which gives the value of the result to be 14.

Without parentheses, the expression would have been evaluated as 2 * 3 + 4, i.e. multiplication operator has higher precedence than the addition operator, that is 6 + 4, which gives the result to be 10.

C++ follows operator precedence and associativity rules, which determine the order in which operators are evaluated. However, these rules may not always align with your intended calculations. Parentheses allow you to override the default order of evaluation and ensure that specific parts of an expression are computed before others.

Conclusion

Operator precedence and associativity rules play a crucial role in determining the order of evaluation in C++ expressions. By understanding these concepts, you can avoid unexpected results and write efficient code. Remember to use parentheses to group operations and explicitly control the order of evaluation when needed.

With the reference table provided, you now have a handy tool to quickly check the precedence of various operators while working on your C++ programs. For a detailed look at a reference table, you can head over to this link. However, you'll cover everything you need to master the C++ in subsequent topics.

6 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo