Skip to content
FollowtheDamnCode

Reference: Operators and Precedence

All the operators, highest precedence first, with the classic traps.

5 minute read

Big idea

Every C operator in one table, from highest precedence (done first) to lowest. When two operators share a level, associativity decides: left-to-right or right-to-left.

The precedence table

LevelOperatorsWhat they areAssociativity
1a() a[i] . -> a++ a--call, index, member, postfixleft → right
2++a --a +a -a ! ~ (type) *p &x sizeofunary, prefix, cast, dereference, address-ofright → left
3* / %multiply, divide, remainderleft → right
4+ -add, subtractleft → right
5<< >>bit shiftsleft → right
6< <= > >=comparisonsleft → right
7== !=equal, not equalleft → right
8&bitwise ANDleft → right
9^bitwise XORleft → right
10|bitwise ORleft → right
11&&logical ANDleft → right
12||logical ORleft → right
13c ? a : bconditional (ternary)right → left
14= += -= *= /= %= <<= >>= &= ^= |=assignmentright → left
15,comma: do left, then right; the value is the rightleft → right

Memory trick, top to bottom: "things attached to a name, then one-operand, then maths, then shifts, then comparisons, then bits, then logic, then ?:, then assignment."

The gotchas worth memorising

ExpressionMeansProbably wanted
x & 1 == 0x & (1 == 0) → always 0(x & 1) == 0
*p++*(p++): read *p, then move pusually that — but (*p)++ to bump the value
a < b < c(a < b) < c — compares 0 or 1 with ca < b && b < c
a = b = 0a = (b = 0) — right to leftchaining works
1 << 2 + 11 << 3 = 8(1 << 2) + 1 = 5
!x == y(!x) == y!(x == y) or x != y
Predict: precedence surprises
#include <stdio.h>

int main(void) {
    int x = 6;
    printf("%d\n", x & 1 == 0);
    printf("%d\n", (x & 1) == 0);
    printf("%d\n", 1 << 2 + 1);
    printf("%d\n", 5 > 3 > 1);
    return 0;
}
What does it print? Show the answer
0
1
8
0

Run and edit it in the app.

5 > 3 > 1 is (5 > 3) > 1, which is 1 > 1 — false.

Operators by family

Arithmetic: + - * / %. Integer / drops the fraction toward zero (-7 / 2 is -3); % takes the sign of the left side (-7 % 2 is -1). See Arithmetic Operators.

Increment/decrement: ++ --. i++ gives the old value, ++i the new. Never use the same variable twice with ++ in one expression (i = i++ is undefined). See Increment and Decrement.

Comparison: == != < <= > >= — each gives 1 (true) or 0 (false).

Logical: && || !. Short-circuit: && stops at the first false, || at the first true — so p != NULL && p->x > 0 is safe. See Relational and Logical Operators.

Bitwise: & | ^ ~ << >>. See Bitwise Operators.

Assignment: = and the compound forms; x += 3 is x = x + 3.

Pointers and members: &x (address of), *p (value at), s.m (member), p->m (member through a pointer, same as (*p).m), a[i] (same as *(a + i)).

Others: sizeof, casts (double) n, the ternary c ? a : b, and the comma operator.

What is 2 + 3 * 4 > 10 && 1 ?

The one rule that beats the table

When in doubt, add brackets. They cost nothing and make the meaning obvious to the next reader. See Operator Precedence.

Key terms

  • Precedence — Which operator is applied first.
  • Associativity — The order among operators of the same precedence.
  • Short-circuit evaluation — && and || skip the right side when the left already decides the answer.

Check yourself

Which binds tighter, == or & ?

Which operators are evaluated right to left?