Foundations — Operator precedence — full table
Before you can read the full precedence table, you need to genuinely understand the tiny pieces it is built from. This page defines every symbol and idea the parent assumes — starting from "what is an operator?" — so that no line of the parent note is a mystery.
1 — What is an expression?
The picture: think of an expression as a little machine with an output slot. You feed it in, a number falls out the bottom.

(Figure 1 — a rounded box labelled a + 3 with an arrow feeding a in from the left and a value 8 dropping out of a slot at the bottom: an expression takes inputs and outputs exactly one value.)
Why the topic needs this: the whole precedence table is a set of rules about how to combine smaller expressions into bigger ones. If you don't see that b * c is itself a value-producing machine that plugs into a + (…), none of the grouping talk makes sense. This is the ground floor — see Expressions and Statements in C.
2 — What is an operator and an operand?
The picture: an operator is a socket with two prongs (for most operators). Each prong plugs into an operand — and that operand may itself be another whole machine that first has to output a value.

(Figure 2 — the flat text a + b * c; teal arrows show + reaching for a and b, orange arrows show * reaching for b and c. The letter b is pulled from both sides — a tug-of-war that precedence must settle.)
Counting prongs (arity): most operators take two operands (a + b) — call them binary. Some take one (-a, !x, a++) — call them unary. One takes three (a ? b : c) — the ternary. You will meet all three arities in the table, so we name them now.
Reveal check:
How many operands does a unary operator take?
-a or !x).Is an operand always a bare number?
(b * c).3 — What is a parse tree?
The parent note keeps saying the compiler builds "a unique parse tree." Here is what that literally is.
The picture: it is an upside-down family tree. The leaves at the bottom are your raw values; each operator up the tree waits for its children to hand it their values, then produces its own.

(Figure 3 — the parse tree of a + b * c: a top + node with a on the left and a * node on the right, and the * node has children b and c. The tree shows only the SHAPE, i.e. that b*c groups together — it says nothing about which branch the CPU computes first in time.)
Why the topic needs this: "precedence decides the tree shape" is the single most important sentence on the parent page. Once you can see the tree, you understand that a + b * c and (a + b) * c are two different trees — the whole point of the rules is to pick one and only one.
4 — Precedence: "who is stronger?"
Back to the tug-of-war: in a + b * c, the * is stronger than +, so * wins b. Result: a + (b * c). The stronger operator ends up lower in the tree, because it forms the inner group that gets built first.
Reveal check:
In a + b * c, which operator ends up lower in the parse tree?
*, because it binds tighter (level 3 binds tighter than level 4), so it grabs b and c first.Does "lower in the tree" mean "computed first in time"?
5 — Associativity: the tie-breaker
Precedence only helps when operators differ in strength. What about a - b - c? Both are - (same level 4). Precedence is silent. We need a second rule.
The picture: imagine the operators reaching for the shared middle operand. L→R means the left one grabs first; R→L means the right one grabs first.

(Figure 4 — two panels. Left: a - b - c with a teal left-pointing grab showing the left - binds first → (a - b) - c. Right: a = b = 0 with a plum right-pointing grab showing the right = binds first → a = (b = 0). L→R is the default; R→L is the rare exception.)
Why the topic needs this: without associativity, a - b - c would be ambiguous even after precedence. And it matters: (a - b) - c and a - (b - c) give different answers for subtraction. Assignment and the ternary (see The Ternary Conditional Operator) are the two famous right-to-left cases the parent highlights.
Reveal check:
Why can't precedence alone group a - b - c?
- operators have equal precedence, so we need associativity (L→R) to break the tie.What is the default associativity for most C operators?
?: are right-to-left.6 — The parentheses ( ) — the override switch
The picture: parentheses are a hard box drawn around part of the expression — nothing outside can reach inside until the box has produced its single value.
Why the topic needs this: every "fix" in the parent's worked examples is the same move — add parentheses to reshape the tree. if ((x & 1) == 0) forces x & 1 to be its own box before == can run.
7 — The top of the table: postfix and unary operators
The very tightest-binding operators (levels 1 and 2) rarely get discussed, but they change tree shape decisively. You must recognise them.
Reveal check:
Why does -a++ mean -(a++)?
++ is level 1 (tightest), unary - is level 2, so ++ grabs a first.Is ~ (bitwise NOT) left- or right-to-left?
8 — The families of operators you'll meet
You don't need to master these yet — you just need to recognise the categories so the table isn't a wall of strange symbols. (Levels 1–2 above; the rest here.)
| Symbol(s) | Family | Plain meaning | Assoc | Go deeper |
|---|---|---|---|---|
+ - * / % |
arithmetic | ordinary maths; % = remainder |
L→R | Expressions and Statements in C |
<< >> |
bit shift | slide bits left/right | L→R | Bitwise Operators |
< <= > >= == != |
relational / equality | comparisons; give 1 (true) or 0 (false) |
L→R | — |
& ^ | |
bitwise | combine bits: AND, XOR, OR | L→R | Bitwise Operators |
&& || |
logical | true/false logic with short-circuit | L→R | Logical Operators and Short-circuit Evaluation |
?: |
ternary | inline if/else | R→L | The Ternary Conditional Operator |
= += ... |
assignment | store a value into a variable | R→L | — |
, |
comma | do this, then that; value is the last | L→R | — |
Reveal check:
What does % mean in C?
7 % 3 = 1).9 — "True" and "false" in C
The relational and logical operators produce truth values, but C has no separate boolean picture — it uses numbers.
Why the topic needs this: the parent's bug if (a = 5) only makes sense once you know a = 5 produces the value 5, which is non-zero, hence true — the if always fires. And the bit-mask trap x & (1 == 0) reduces to x & 0 because 1 == 0 is false, i.e. 0.
Prerequisite map
The diagram below reads top to bottom: a raw value and an operator + operand pair both feed the idea of an expression; expressions plus arity build a parse tree; the tree needs precedence (strength) and associativity (tie-break) to become unique; those two, together with parentheses, the truthiness rule, and the operator families, are exactly what the full precedence table assembles.
Equipment checklist
Self-test: can you answer each before revealing?
An expression is
b = 5 produces 5).An operator vs an operand
+); the operands are the sub-expressions it works on — each itself producing a value.Can an operand be a whole sub-expression
(b * c), not just a bare literal.Arity means
A parse tree shows
Precedence answers
"Lower in the tree" means
Associativity answers
The default associativity is
?: are right-to-left.Level-1 operators include
() call, [] subscript, . and -> member access, and postfix ++ -- — they bind tightest of all.Level-2 unary operators include
++ --, unary + -, !, ~, * deref, & address-of, sizeof, (type) cast — all right-to-left.Parentheses ( ) do what to the rules
In C, false and true are
0 is false; any non-zero value is true.& vs &&
& is bitwise (bit-by-bit); && is logical (true/false, short-circuits) — different operators, different levels.Connections
- Operator precedence — full table (index 5.1.5)
- Expressions and Statements in C
- Bitwise Operators
- Logical Operators and Short-circuit Evaluation
- Sequence Points and Undefined Behaviour
- Type Casting and Conversions
- The Ternary Conditional Operator