Operator Precedence and Associativity in C
Learn via video course

Overview
Operator Precedence in C is used to determine the sequence in which different operators will be evaluated if two or more operators are present in an expression. The associativity of operators is used to determine whether an expression will be evaluated from left-to-right or from right-to-left if there are two or more operators of the same precedence.
Scope of the Article
- Operator Precedence in C and its examples
- Associativity of Operators in C and its examples
- Precedence and Associativity table
What is Operator Precedence in C?
Let us say we want to evaluate the expression 9+6/3 using the C language. When C evaluates this expression, we might think that the compiler may get confused about what operation should it perform first. If 9+6 is calculated first, the output will be 5. And if 6/3 is calculated first, the output will be 11. But the compiler never gets confused in situations like these because of the operator precedence in C. The output of the above expression will always be 11 and not 5.
The operator precedence in C determines how an expression with multiple operators will be evaluated. Some operators have a higher level of precedence than others. In the above example, the answer was 11 because multiplication has higher precedence than addition.
The operator precedence and associativity table are given below. From that table, we can see that some operators have the same precedence while some have higher precedence than others. In an expression, the precedence of an operator is only meaningful if other operators with higher or lower precedence are present.
We can change the sequence of evaluation of an expression with the use of parenthesis ().
Parentheses have the highest precedence among all operators in C. So, if parentheses are present in an expression, the entire sub-expression between the parentheses is evaluated immediately when the term is required. If we have nested parenthesis (parenthesis inside another parenthesis), then the innermost parenthesis is evaluated first, and the outermost parenthesis is evaluated at last.
Examples of Operator Precedence in C
Example 1:
The precedence of multiplication is the highest, while the precedence of the assignment operator is the lowest among the three operators. So, multiplication will be done first (4*3 = 12), which will be followed by subtraction (15-12 = 3), and the final value of the expression will be assigned to the variable var (var = 3).
Example 2:
Answer: 12
In the above example, we have three parentheses. As the sub-expression(s) inside the parentheses will get evaluated first, the given expression(s) will convert to 6 + (20 / 10) * 3. Upon further evaluation, the expression becomes 6 + 2 * 3 as multiplication has higher precedence than addition, 2 * 3 is calculated first and then the result is added to 6. Hence, the answer becomes 12.
What is Operator Associativity in C?
Let us say we want to calculate 12/3*2 using the C language. From the precedence and associativity table given below, we can see that the division and multiplication operators have the same precedence. So, why the compiler does not get confused about what to calculate first? Division or multiplication?
This confusion is avoided using the associativity of operators.
When two operators have the same precedence, their associativity comes into play. Because division and multiplication operators have associativity (left to right), the operator written on the left gets evaluated first. Hence, in the above example, the division is done before multiplication.
The associativity of operators is used to determine the direction (left-to-right or right-to-left) in which an expression will be evaluated. Associativity is only helpful if two expressions' operators have the same precedence.
Examples of Operator Associativity in C
Example 1:
Since multiplication has the highest precedence, the multiplication operation will be performed first. Addition and subtraction operators have the same precedence, but because their associativity is left to right, the addition operation will be performed first, followed by subtraction.
The above expression will yield 12 as its value.
Example 2:
The operators == and != have the same precedence. Because their associativity is left to right, the == operation was performed first, which yielded 0 as its output. Then, the != operation was performed between 0 and 5. So, the final output that we got was 1.
Example 3:
Output:
Let us first simplify the given expression by evaluating the parenthesis: ++a * 11 % 35 - 28 / 7. As the value of a is 5, the value of ++a in the given expression will become 6. Now, the multiplication and the remainder operators have equal precedence with left-to-right associativity (refer to the table below). So, multiplication will be done first (6 * 11 = 66), followed by the remainder operation (66 % 35 = 31). After these two calculations, the expression simplifies to 31 - 28 / 7. As the division has higher precedence than subtraction, the division will be done before subtraction. So, the final answer we get is 31 - 4 = 27.
When is Associativity Used?
Associativity is used when two operators of the same precedence appear in an expression. Associativity is of no use in situations where the precedence of operators is different.
It is important to note that the associativity of an operator does not define the order in which the operands will be evaluated.
For example:
Output:
In the above example, associativity was not used by the compiler. Whether func1() or func2() will be called first depends totally on the compiler. We have defined a global variable var in the above example. The value of var that will be printed depends on whether func1() or func2() will be called first. In this case, func1() was called first, so the value of var became 1. After that, func2() was called. So, the value of var became 2. Hence, 2 was printed in the output.
Associativity is only used when the same precedence appears in an expression. For example, func1() - func2() - func3() will be considered as ((func1() - func2()) - func3()). But among (func1() - func2()), which operand will evaluate first depends on the compiler.
Operators with the same precedence have the same associativity
Operators with the same precedence must have the same associativity. Otherwise, it would not be possible for the compiler to decide the direction of evaluation of an expression that contains two operators with the same precedence but different associativity.
Let us take an example to understand this concept:
From the operator precedence and associativity table, we can see that the division and remainder operators have the same precedence. Now, let's assume that the division operator has associativity from left to right, while the remainder operator has associativity from right to left. Because of this assumption in place, the compiler will not be able to decide what to evaluate first: 18 / 9 (because of the left to right associativity) or 9 % 2 (because of the right to left associativity). This is why operators with the same precedence need to have the same associativity. As both operators have left-to-right associativity, we can easily calculate the output in the above example. 18 / 9 will be evaluated first, followed by % 2. Hence, the output will be 0.
For example, multiplication and division operators have the same precedence and associativity. Similarly, addition and subtraction operators have the same precedence and associativity.
Precedence and Associativity of Postfix ++ and Prefix ++
The precedence of postfix ++ is more than that of prefix ++. The associativity of postfix ++ is left to right, while the associativity of prefix ++ is right to left.
Example 1:
Output:
Both prefix ++ and * have the same precedence and they both have associativity from right to left. So, ++p is treated as ( ++(p) ). This is why arr[0] = 11, arr[1] = 20, *p = 11.
Example 2:
Output:
Prefix ++ and postfix ++ have a higher precedence than addition. So, the addition will be the last operation among the three. The sub-expression a++ means to use the present value of a and then increase its value. So, the expression becomes 1 + ++a while the value of a becomes 2. The sub-expression ++a means, increase the value of a and then use it in the expression. So the value of a becomes 3, and the expression becomes 1 + 3. So, the final answer we get is 4.
Precedence of Comma (,)
Among all operators, the comma has the lowest precedence.
For example:
Output:
Since the comma has the least precedence among all operators, the assignment operator (=) will get evaluated before the comma. So, the number 10 will be assigned to the variable var, and the number 20 will not be assigned to anything. In other words, the expression var = 10, 20 will be treated as ((var = 10), 20). This is why the output we get is var = 10.
Chaining of Comparison Operators is not possible
If we think logically, a > b > c (chaining of comparison operators) means a is greater than b (a > b) and b is greater than c (b > c). However, we should note that this is not the case in the C language. Chaining comparison operators are not feasible in C programming because of the associativity of operators. Because the associativity of the > operator is left to right, in the expression a > b > c, a > b is evaluated first, and the result (1 if the expression is true or 0 otherwise) is then compared with c (0 or 1 > c).
For example:
Output:
Even though the expression 3 == 3 == 3 should be true by logic, we get the output as false. This happens because C treats the above expression like this: ((3 == 3) == 3). As 3 == 3, the expression transforms to ((1) == 3) (number 1 depicts means true). Because 1 is not equal to 3, we get False as the output.
Operators Precedence & Associativity Table
The precedence and associativity of different operators in the C language are mentioned in the table below. This table shows that the operators with the same precedence have associativity in the same direction. Also, we can see that comma has the least precedence, followed by the assignment operator(s).
Precedence | Category | Operator | Left to Right Assocciativity |
---|---|---|---|
1 | Postfix increment | ++ | Yes |
Postfix decrement | -- | Yes | |
Expression of function | () | Yes | |
Expression of array | [] | Yes | |
Direct selection of members | . | Yes | |
Indirect selection of member | -> | Yes | |
2 | Prefix increment | ++ | No |
Prefix decrement | -- | No | |
Cast | (type) | No | |
Unary plus or minus | + - | No | |
Logical NOT | ! | No | |
Bitwise NOT | ~ | No | |
Dereference | * | No | |
Address of | & | No | |
Size of | sizeof | No | |
3 | Multiply, divide, or remainder | * / % | Yes |
4 | Add or subtract | + - | Yes |
5 | Bitwise left shift | << | Yes |
Bitwise right shift | >> | Yes | |
6 | Relational operator < | < | Yes |
Relational operator ≤ | <= | Yes | |
Relational operator > | > | Yes | |
Relational operator ≥ | >= | Yes | |
7 | Relational operator = | == | Yes |
Relational operator ≠ | != | Yes | |
8 | Bitwise AND | & | Yes |
9 | Bitwise XOR | ^ | Yes |
10 | Bitwise OR | | | Yes |
11 | Logical AND | && | Yes |
12 | Logical OR | || | Yes |
13 | Ternary conditional | ?: | No |
14 | Assignment | = | No |
Addition or subtraction assignment | += -= | No | |
Multiplication or division assignment | *= /= | No | |
Modulus assignment | %= | No | |
Bitwise AND assignment | &= | No | |
Bitwise exclusive OR and inclusive OR assignment | ^= |= | No | |
Bitwise left shift assignment | <<= | No | |
Bitwise right shift assignment | >>= | No | |
15 | Comma | , | Yes |
Conclusion
- The operator precedence in C helps to evaluate an expression when we have more than one operator in an expression.
- The associativity of operators is useful when two operators in an expression have the same precedence.
- Operators with equal precedence have associativity in the same direction.