This page is the case-by-case drill room for the precedence table. The parent note taught the rulebook; here we hunt down every kind of expression the rules can produce and work each one to the ground.
Before touching examples, remember the two words the whole topic rests on — build them from zero, exactly like the parent did:
Every worked example below says things like "* is level 3." That number is just the row number of the parent table, counted from the tightest-binding operators (row 1) down to the loosest (row 15). Lower number = stronger. Here is the compact legend so you never have to flip back:
Every precedence puzzle in C falls into one of these case classes. Each row is a distinct trap the rules can spring. The worked examples below are labelled with the cell they cover, and together they hit every row.
Cell
Case class
The trap it hides
Covered by
A
Different-precedence arithmetic
* claims operands before +/-
Ex 1
B
Equal-precedence, L→R tie
a-b-c must go left-first
Ex 2
C
Equal-precedence, R→L tie
assignment / ternary chain right-first
Ex 3, Ex 7
D
Cross-family surprise (bitwise vs equality)
`& ^
sit **below**== !=`
E
Shift vs arithmetic
+ beats <<
Ex 5
F
Unary vs postfix (degenerate 1-operand)
postfix ++ beats unary -
Ex 6
G
Real-world word problem
grouping changes a computed quantity
Ex 8
H
Exam twist / undefined-behaviour edge
precedence is irrelevant here
Ex 9
I
Zero / degenerate operand (short-circuit)
second operand never runs
Ex 10
J
Comma operator (lowest precedence)
a = 1, 2 is not a = (1,2)
Ex 11
K
Level-1 postfix cluster (calls, member, [], ++)
*p.x, f()->b++ group surprisingly
Ex 12
L
Cast (type) vs unary / deref
(int)x + y casts only x
Ex 13
Read the table as a checklist: by Example 13 there is no shape of expression left that can surprise you.
Figure 1 — parse tree of a + b*c - d. A binary tree: the root is -; its left child is + and right child is the leaf d. The + node has left leaf a and right child *, and that * node (drawn in magenta, sitting deepest) has leaves b and c. Arrows label the magenta * as "binds tightest, done first" and the root - as "binds loosest, done last".
The red subtree (3*4) is deepest because it binds tightest; the - sits at the root because it is the loosest operator here and so is applied last.
Figure 2 — two rival trees for a - b - c. Left tree (magenta root, C's meaning): ((a-b)-c), so the deepest bracket is a-b. Right tree (violet root, the wrong reading): (a-(b-c)), deepest bracket b-c. Captions read "C's meaning (L→R): = 3" over the left and "wrong (R→L): = 9" over the right, showing the answer flips with the grouping.
Figure 3 — parse tree of a = b = 5. Root = (violet), left leaf a, right child a second = (magenta) whose leaves are b and 5. An arrow marks the inner magenta = as "inner (b=5) done first, yields value 5" and the root as "outer a = 5 last", visualising the right-to-left grouping.
Figure 4 — buggy vs fixed bit-mask trees. Left (violet root, "BUG"): x & (1==0), where == is the deeper node, so x gets ANDed with the comparison result. Right (magenta root, "FIX"): (x & 1) == 0, where & is now the deeper node, so the lowest bit is extracted before the equality test. Captions: "BUG: x & (10) → 0" and "FIX: (x & 1)0 → 1".
Figure 5 — parse tree of 1 << 2 + 3. Root << (violet), left leaf 1, right child + (magenta) with leaves 2 and 3. An arrow tags the + node "+ groups first (level 4 < 5), so 2+3 = 5", and a caption reads "1 << (2+3) = 1 << 5 = 32".
Figure 6 — vertical chain for -a++. Three stacked nodes: top unary - (violet), middle postfix ++ (magenta), bottom leaf a. Arrows explain that ++ binds tightest (level 1) so a++ yields the old value 5, and then - negates that 5 giving b = -5 while a becomes 6.
Figure 7 — nested ternary tree. Root ternary "?: a" (violet) with left leaf b and right child a second ternary "?: c" (magenta) whose branches are d and e. Arrows note "a=0 false → take else branch" pointing at the inner ternary and "c=1 true → d = 8" pointing at leaf d; caption "a ? b : (c ? d : e) (R→L) → x = 8".
Figure 8 — comma trap, two trees. Left ("a = 1, 2;"): root is , (violet), whose left child is the = node (orange) with leaves a and 1, and whose right leaf is 2; caption "a = 1, 2; → a == 1", with an arrow noting "= binds tighter than , so a=1 happens". Right ("a = (1,2);"): root is = (magenta) with left leaf a and right child a , node (violet) over leaves 1 and 2; caption "a = (1, 2); → a == 2".
Ex 1 — a + b*c - d with a=2,b=3,c=4,d=1 groups and evaluates to what? ::: ((2 + (3*4)) - 1) = 13.
Ex 2 — the value C guarantees for 10 - 4 - 3? ::: 3 (left-associative), not 9.
Ex 3 — after a = b = 5, what is a? ::: 5 (right-associative assignment).
Ex 4 — what does 6 & 1 == 0 evaluate to? ::: 0 (because == outranks &, giving 6 & 0).
Ex 5 — value of 1 << 2 + 3? ::: 32 (+ beats <<, so 1 << 5).
Ex 6 — after b = -a++ with a=5, what are b and a? ::: b = -5, a = 6.
Ex 7 — value of 0 ? 1 : 1 ? 8 : 9? ::: 8.
Ex 8 — value of s1 + s2 + s3/3 with 10,20,30, and the correct mean? ::: bug gives 40; correct mean needs parentheses → 20.
Ex 9 — value of i = i++ + 1? ::: undefined behaviour — no valid numeric answer.
Ex 10 — value of 1 || 0 && 1, and is 0 && 1 evaluated? ::: 1; and no, it is short-circuited away.
Ex 11 — a after a = 1, 2; versus a = (1, 2);? ::: 1 in the first, 2 in the second.
Ex 12 — how do *p.x and f()->b++ group? ::: *(p.x) (member beats deref) and ((f())->b)++ (all level-1, L→R).
Ex 13 — value of (int)7.8 + 4, and does the cast reach y? ::: 11; the cast binds only x (level 2 > +), so y is untouched.