5.1.5 · D4C Programming

Exercises — Operator precedence — full table

2,463 words11 min readBack to topic

Before we start, one picture of the whole idea — precedence turns flat text into ONE tree.

Figure — Operator precedence — full table

The two operators + and * both want the operand b. The stronger one (*, level 3) wins the tug-of-war, so b joins c first. That is the entire game, repeated.


Level 1 — Recognition

Goal: read the table, no arithmetic yet.

Recall Solution

Look up each level number in Operator precedence — full table:

  • % → level 3 (multiplicative)
  • == → level 7 (equality)
  • || → level 12 (logical OR)
  • = → level 14 (assignment) Smaller number binds tighter, so the order tightest→loosest is:
Recall Solution

From the table's Assoc column:

  • - (additive, lvl 4) → left-to-right
  • = (assignment, lvl 14) → right-to-left
  • ?: (ternary, lvl 13) → right-to-left
  • . (member, lvl 1) → left-to-right Answer set: {L, R, R, L}.
Recall Solution
  • + lvl 4 < 7 → tighter
  • & lvl 8 > 7 → looser (the famous surprise!)
  • < lvl 6 < 7 → tighter
  • && lvl 11 > 7 → looser So +, < beat ==; &, && lose to ==.

Level 2 — Application

Goal: parse one real expression correctly.

Recall Solution
  1. Highest precedence present: * and / (both lvl 3). Group them first — they tie, so left-to-right, but they act on separate operands here: (b*c) and (d/e).
  2. Now + and - (both lvl 4) tie → left-to-right: leftmost first.
Recall Solution

+ (lvl 4) is tighter than << (lvl 5). So it groups as 1 << (2 + 3). Answer: 32 (not 7).

Recall Solution

== (lvl 7) beats & (lvl 8), so it parses as x & (1 == 0).

  • 1 == 0 is false → 0.
  • 6 & 0 = 0. Answer: 0 (the intended "is x even?" check is broken; see Bitwise Operators).
Recall Solution
  1. + (lvl 4) beats = (lvl 14): right side is 5 + 2 = 7.
  2. = is right-associative → a = (b = 7).
  3. Inner b = 7 yields the value 7; then a = 7. Answer: a = 7, b = 7.

Level 3 — Analysis

Goal: explain WHY a subtle grouping happens.

Recall Solution

Both - are lvl 4 → tie → left-to-right, so the leftmost - binds first: The wrong reading a - (b - c) = 10 - (3 - 2) = 10 - 1 = 9 would need right-associativity, which subtraction does not have. Answer: 5. Left-associativity is what makes chained subtraction behave like ordinary arithmetic.

Recall Solution

&& (lvl 11) beats || (lvl 12), so it groups a || (b && c).

  • a is 1 (true) → by short-circuit (see Logical Operators and Short-circuit Evaluation) the right side b && c is never evaluated.
  • Whole expression = 1. Answer: 1. Even though b && c = 0, it is skipped entirely.
Recall Solution

Postfix ++ (lvl 1) beats unary - (lvl 2), so it groups -(a++).

  • a++ yields the old value 5, then a becomes 6.
  • Negate: b = -5. Answer: b = -5, a = 6.
Recall Solution

A cast (type) is lvl 2 (unary), / is lvl 3. Lvl 2 binds tighter, so the cast grabs a first: ((double)a) / 2.

  • (double)7 = 7.0
  • 7.0 / 2 = 3.5 (double division; see Type Casting and Conversions). Answer: 3.5. If the cast had been looser we'd get (double)(7/2) = (double)3 = 3.0 — but it isn't.

Level 4 — Synthesis

Goal: combine several precedence layers in one expression.

Recall Solution

Rank the operators present: << (lvl 5), == (lvl 7), & (lvl 8). Tightest first.

  1. 1 << 1 = 2. Expression is now x & 3 == 2.
  2. == beats &: 3 == 20. Now x & 0.
  3. 5 & 0 = 0. Answer: 0. (Intended (x & 3) == (1 << 1) would be (5&3)==2 = (1)==2 = 0 here too — coincidence — but the reasons differ, which is the point.)
Recall Solution

Precedence order: +,- (lvl 4) > > (lvl 6) > ?: (lvl 13). The ternary is nearly loosest, so it splits last:

  • a > 34 > 3 → true.
  • Take the middle arm: a + 1 = 5. Answer: 5. (See The Ternary Conditional Operator.)
Recall Solution

?: is right-associative → a ? b : (c ? d : e).

  • a = 0 (false) → take the else arm (c ? d : e).
  • c = 1 (true) → that inner ternary is d = 20. Answer: 20. Reads as if/else-if/else.
Recall Solution

> (lvl 6) beats = (lvl 14), so it groups a = (b > 3).

  • b > 35 > 31.
  • a = 1; the whole expression's value is also 1. Answer: expression = 1, a = 1. Note a = b > 3 is NOT (a = b) > 3.

Level 5 — Mastery

Goal: predict real machine behaviour, including where C refuses to promise anything.

Recall Solution

No. Precedence only fixes the tree: f() + (g() * h()). It does not fix the time order of the calls. The compiler may call f(), g(), h() in any order (they are unsequenced relative to each other). Answer: not guaranteed. If you need an order, introduce a sequence point — see Sequence Points and Undefined Behaviour.

Recall Solution

i is modified twice (once by ++, once by =) and also read, with no sequence point between them. That is undefined behaviour — the standard makes no promise about the result, and precedence cannot rescue it. Answer: undefined; do not write this. Precedence tells you the shape i = ((i++) + 1) but shape ≠ legality here.

Recall Solution

&& groups as (a != 0) && (10 / a > 2).

  • Left operand a != 00 != 0 → false.
  • && short-circuits: the right operand is never evaluated, so 10 / a (a divide-by-zero!) never happens.
  • r = 0. Answer: r = 0, division skipped. Short-circuit here prevents a crash.
Recall Solution

Level numbers: <<(5), +(4), >(6), &&(11), ==(7). Group tightest first.

  1. + (4): 1 + b = 1 + 3 = 4. → a << 4 > c && a == 2
  2. << (5): a << 4 = 2 << 4 = 2 \times 16 = 32. → 32 > c && a == 2
  3. > (6): 32 > 11. == (7): a == 21. → 1 && 1
  4. && (11): 1 && 1 = 1. Answer: 1.

Active recall

Rank tightest→loosest: %, ||, ==, =
% > == > || > = (levels 3, 7, 12, 14).
What does 1 << 2 + 3 equal?
32, because + (lvl 4) beats << (lvl 5): 1 << 5.
How does x & 1 == 0 group?
x & (1 == 0), since == (lvl 7) outranks & (lvl 8).
Value of (double)7 / 2?
3.5 — the cast is unary (lvl 2) and grabs only 7, giving 7.0 / 2.
Does precedence set the order of function calls in f()+g()*h()?
No — only the tree shape; call order is unsequenced.
Why is i = i++ + 1; undefined?
i is modified twice and read with no sequence point between.

Connections