Operator Precedence and Associativity in C
Operator precedence and associativity are rules that decide the order in which parts of an expression are calculated. Precedence tells us which operators should be evaluated first, while associativity determines the direction (left to right or right to left) in which operators with the same precedence are evaluated.
Let's take a look at an example:
#include <stdio.h>
int main() {
int a = 6, b = 3, c = 4;
int res;
// Precedence and associativity applied here
res = a + b * c / 2;
printf("%d", res);
return 0;
}
Output
12
Explanation: The above expression is evaluated as 6 + ( (3 * 4) / 2) = 16, not (6 + 3) * (4 / 2) = 12. So what guided the compiler to evaluate the expression in this way? It is actually the precedence and associativity of the operators used in this expression.
In this article, let's discuss operator precedence, operator associativity, and the precedence table that determines the priority of operators in expressions in C language.
Operator Precedence
Operator precedence determines which operation is performed first in an expression with more than one operator with different precedence. Let's try to evaluate the following expression,
10 + 20 * 30
The expression contains two operators, + (addition) and * (multiplication). According to operator precedence, multiplication (*) has higher precedence than addition (+), so multiplication is checked first. After evaluating multiplication, the addition operator is then evaluated to give the final result.
We can verify this using the following C program
#include <stdio.h>
int main() {
// Printing the value of same expression
printf("%d", 10 + 20 * 30);
return 0;
}
Output
610
As we can see, the expression is evaluated as,10 + (20 * 30) but not as (10 + 20) * 30 due to * operator having higher precedence.
Operator Associativity
Operator associativity is used when two operators of the same precedence appear in an expression. Associativity can be either from Left to Right or Right to Left. Let's evaluate the following expression,
100 / 5 % 2
The division (/
) and modulus (%
) operators have the same precedence, so the order in which they are evaluated depends on their left-to-right associativity. This means the division is performed first, followed by the modulus operation. After the calculations, the result of the modulus operation is determined.

We can verify the above using the following C program:
#include <stdio.h>
int main() {
// Verifying the result of the same expression
printf("%d", 100 / 5 % 2);
return 0;
}
Output
0
Operators Precedence and Associativity are two characteristics of operators that determine the evaluation order of sub-expressions.
Example of Operator Precedence and Associativity
In general, operator precedence and associativity are applied together in expressions. Consider the expression exp = 100 + 200 / 10 - 3 * 10, where the division (/) and multiplication (*) operators have the same precedence but are evaluated before addition (+) and subtraction (-). Due to left-to-right associativity, the division is evaluated first, followed by multiplication. After evaluating the division and multiplication, the addition and subtraction are evaluated from left to right, giving the final result.
Again, we can verify this using the following C program.
#include <stdio.h>
int main() {
// getting the result of the same expression as the
// example
int exp = 100 + 200 / 10 - 3 * 10;
printf("%d", exp);
return 0;
}
Output
90
Operator Precedence and Associativity Table
The following tables list the C operator precedence from highest to lowest and the associativity for each of the operators:
Precedence | Operator | Description | Associativity |
---|---|---|---|
1 | () | Parentheses (function call) | Left-to-Right |
[] | Array Subscript (Square Brackets) | ||
. | Dot Operator | ||
-> | Structure Pointer Operator | ||
++ , -- | Postfix increment, decrement | ||
2 | ++ / -- | Prefix increment, decrement | Right-to-Left |
+ / - | Unary plus, minus | ||
! , ~ | Logical NOT, Bitwise complement | ||
(type) | Cast Operator | ||
* | Dereference Operator | ||
& | Addressof Operator | ||
sizeof | Determine size in bytes | ||
3 | *,/,% | Multiplication, division, modulus | Left-to-Right |
4 | +/- | Addition, subtraction | Left-to-Right |
5 | << , >> | Bitwise shift left, Bitwise shift right | Left-to-Right |
6 | < , <= | Relational less than, less than or equal to | Left-to-Right |
> , >= | Relational greater than, greater than or equal to | ||
7 | == , != | Relational is equal to, is not equal to | Left-to-Right |
8 | & | Bitwise AND | Left-to-Right |
9 | ^ | Bitwise exclusive OR | Left-to-Right |
10 | | | Bitwise inclusive OR | Left-to-Right |
11 | && | Logical AND | Left-to-Right |
12 | || | Logical OR | Left-to-Right |
13 | ?: | Ternary conditional | Right-to-Left |
14 | = | Assignment | Right-to-Left |
+= , -= | Addition, subtraction assignment | ||
*= , /= | Multiplication, division assignment | ||
%= , &= | Modulus, bitwise AND assignment | ||
^= , |= | Bitwise exclusive, inclusive OR assignment | ||
<<=, >>= | Bitwise shift left, right assignment | ||
15 | , | comma (expression separator) | Left-to-Right |
Easy Trick to Remember the Operators Associtivity and Precedence: PUMA'S REBL TAC
where, P = Postfix, U = Unary, M = Multiplicative, A = Additive, S = Shift, R = Relational, E = Equality, B = Bitwise, L = Logical, T = Ternary, A = Assignment and C = Comma
Important Points
There are a few important points and cases that we need to remember for operator associativity and precedence which are as follows:
Associativity is only used when there are two or more operators of the same precedence.
The point to note is associativity doesn't define the order in which operands of a single operator are evaluated. For example, consider the following program, associativity of the + operator is left to right, but it doesn't mean f1() is always called before f2(). The output of the following program is in-fact compiler-dependent.
// Associativity is not used in the below program.
// Output is compiler dependent.
#include <stdio.h>
int x = 0;
int f1()
{
x = 5;
return x;
}
int f2()
{
x = 10;
return x;
}
int main()
{
int p = f1() + f2();
printf("%d ", x);
return 0;
}
Output
10
You can check this article for more details.
We can use parenthesis to change the order of evaluation
Parenthesis ( ) got the highest priority among all the C operators. So, if we want to change the order of evaluation in an expression, we can enclose that particular operator in ( ) parenthesis along with its operands.
Example
Consider the given expression
100 + 200 / 10 - 3 * 10
= 90
But if we enclose 100 + 200 in parenthesis, then the result will be different.
(100 + 200) / 10 - 3 * 10 = 0
= 0
As the + operator will be evaluated before / operator.
All operators with the same precedence have the same associativity.
This is necessary, otherwise, there won't be any way for the compiler to decide the evaluation order of expressions that have two operators of the same precedence and different associativity. For example + and - have the same associativity.
Precedence and associativity of postfix ++ and prefix ++ are different.
The precedence of postfix ++ is more than prefix ++, their associativity is also different. The associativity of postfix ++ is left to right and the associativity of prefix ++ is right to left. Check this article for more details.
Comma has the least precedence among all operators and should be used carefully.
For example, consider the following program, the output is 1.
#include <stdio.h>
int main()
{
int a;
// Evaluated as (a = 1), 2, 3
a = 1, 2, 3;
printf("%d", a);
return 0;
}
Output
1
There is no chaining of comparison operators in C
In Python, an expression like "c > b > a" is treated as "c > b and b > a", but this type of chaining doesn't happen in C. For example, consider the following program. The output of the following program is "FALSE".
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
// (c > b > a) is treated as ((c > b) > a), associativity of '>'
// is left to right.
//Therefore the value becomes ((30 > 20) > 10)
// which becomes (1 > 10)
if (c > b > a)
printf("TRUE");
else
printf("FALSE");
return 0;
}
Output
FALSE
Conclusion
It is necessary to know the precedence and associativity for the efficient usage of operators. It allows us to write clean expressions by avoiding the use of unnecessary parenthesis. Also, it is the same for all the C compilers so it also allows us to understand the expressions in the code written by other programmers.
Also, when confused about or want to change the order of evaluation, we can always rely on parenthesis ( ). The advantage of brackets is that the reader doesn't have to see the table to find out the order.