COperator Precedence & Associativity

Operator Precedence & Associativity

When an expression contains multiple operators, C needs rules to decide which operator applies first. Precedence determines which operator binds tighter (is evaluated first) when different operators compete for the same operand. Associativity determines the order when operators of the same precedence appear together — either left-to-right or right-to-left.
Precedence Table (Highest to Lowest)

Precedence

Operators

Associativity

1 (highest)

() [] . -> (postfix ++/--)

Left to right

2

! ~ (unary +/-) (prefix ++/--) sizeof (type)

Right to left

3

* / %

Left to right

4

+ - (binary)

Left to right

5

<< >>

Left to right

6

< <= > >=

Left to right

7

== !=

Left to right

8

& (bitwise AND)

Left to right

9

^ (bitwise XOR)

Left to right

10

| (bitwise OR)

Left to right

11

&&

Left to right

12

||

Left to right

13

?: (ternary)

Right to left

14

= += -= etc.

Right to left

15 (lowest)

, (comma operator)

Left to right

Note
Notice that bitwise &, ^, and | bind looser than the relational and equality operators, and even looser than the shift operators. This surprises many people and is a frequent source of subtle bugs when mixing bitwise operators with comparisons — always use parentheses in that situation.
Use Parentheses for Clarity

Even when you know the precedence table by heart, relying on it in real code makes the code harder for others (and future you) to read quickly. Adding parentheses around the intended grouping costs nothing at runtime and removes all ambiguity.

C
/* Technically correct, but forces the reader to recall precedence rules */
int result = a + b * c > d && e | f;

/* Much clearer with explicit grouping — same behavior, obvious intent */
int resultClear = (a + (b * c) > d) && (e | f);
Worked Example: Mixing &&, ||, Bitwise, and Shift

Consider the following expression, which mixes several operator categories:

C
int result = 1 << 2 & 6 == 6 || 8 >> 1;

Resolving it step by step using the precedence table above:

  • == (precedence 7) binds tighter than & and <</>>? No — check the table: <</>> are precedence 5, == is precedence 7, so shifts bind tighter than ==. Evaluate shifts first: 1 << 2 becomes 4, and 8 >> 1 becomes 4

  • Expression is now: 4 & 6 == 6 || 4

  • == (7) binds tighter than & (8), so 6 == 6 evaluates first, giving 1

  • Expression is now: 4 & 1 || 4

  • & (8) binds tighter than || (12), so 4 & 1 evaluates next, giving 0

  • Expression is now: 0 || 4, which evaluates to 1 (true), since 4 is truthy

  • Final result: result = 1

Note
This example is exactly why experienced C programmers add parentheses around bitwise operations mixed with comparisons or logical operators — the intended grouping is rarely obvious at a glance, and the actual precedence rules can differ from what most people intuitively assume.
  • Precedence decides which operator applies first among different operators

  • Associativity decides the order among operators of equal precedence

  • Bitwise &, ^, | bind looser than relational and equality operators — a common surprise

  • When mixing operator categories, use parentheses rather than relying on memorized precedence