5.1.5 · D3C Programming

Worked examples — Operator precedence — full table

4,978 words23 min readBack to topic

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:


The "level N" key — read this first

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:

Level Operators (as used below)
1 () grouping, [], ->, ., postfix ++ --
2 unary + - ! ~, prefix ++ --, *(deref), &(addr), sizeof, (type)
3 * / %
4 + - (binary)
5 << >>
6 < <= > >=
7 == !=
8 & (bitwise AND)
9 ^ (bitwise XOR)
10 `
11 &&
12 `
13 ?: (ternary)
14 = and compound assignments
15 , (comma)

The scenario matrix

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.


Worked examples

Cell A — different-precedence arithmetic

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".

Figure — Operator precedence — full table

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.


Cell B — equal precedence, left-to-right

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 — Operator precedence — full table

Cell C — equal precedence, right-to-left (assignment)

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 — Operator precedence — full table

Cell D — cross-family surprise (bitwise below equality)

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 — Operator precedence — full table

Cell E — shift versus arithmetic

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 — Operator precedence — full table

Cell F — unary versus postfix (degenerate single-operand)

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 — Operator precedence — full table

Cell C (again) — ternary chain, right-to-left

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 — Operator precedence — full table

Cell G — real-world word problem


Cell H — exam twist / precedence is a red herring


Cell I — zero / degenerate operand (short-circuit)


Cell J — the comma operator (lowest precedence of all)

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".

Figure — Operator precedence — full table

Cell K — the level-1 postfix cluster (calls, member, subscript, postfix ++)


Cell L — the cast (type) versus unary and dereference


Recall Self-test the whole matrix

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.


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

Case-class map

different levels

equal level

left to right

left to right

right to left

yes

no

yes

no

Any C expression

How many precedence levels

Strongest groups first

Associativity

A arithmetic times over plus

D bitwise below equality

E shift below arithmetic

F postfix over unary

G word problem grouping

L cast reaches one operand

B left to right minus

K level one cluster

C assignment and ternary

J comma weakest of all

Same variable read and written

H undefined behaviour

Does result settle early

I short circuit skips operand

Both operands evaluated