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
| Level | Operators | What they are | Associativity |
|---|---|---|---|
| 1 | a() a[i] . -> a++ a-- | call, index, member, postfix | left → right |
| 2 | ++a --a +a -a ! ~ (type) *p &x sizeof | unary, prefix, cast, dereference, address-of | right → left |
| 3 | * / % | multiply, divide, remainder | left → right |
| 4 | + - | add, subtract | left → right |
| 5 | << >> | bit shifts | left → right |
| 6 | < <= > >= | comparisons | left → right |
| 7 | == != | equal, not equal | left → right |
| 8 | & | bitwise AND | left → right |
| 9 | ^ | bitwise XOR | left → right |
| 10 | | | bitwise OR | left → right |
| 11 | && | logical AND | left → right |
| 12 | || | logical OR | left → right |
| 13 | c ? a : b | conditional (ternary) | right → left |
| 14 | = += -= *= /= %= <<= >>= &= ^= |= | assignment | right → left |
| 15 | , | comma: do left, then right; the value is the right | left → 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
| Expression | Means | Probably wanted |
|---|---|---|
x & 1 == 0 | x & (1 == 0) → always 0 | (x & 1) == 0 |
*p++ | *(p++): read *p, then move p | usually that — but (*p)++ to bump the value |
a < b < c | (a < b) < c — compares 0 or 1 with c | a < b && b < c |
a = b = 0 | a = (b = 0) — right to left | chaining works |
1 << 2 + 1 | 1 << 3 = 8 | (1 << 2) + 1 = 5 |
!x == y | (!x) == y | !(x == y) or x != y |
#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
0Run 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?