Programming Fundamentals Using C++

L06 · Type Conversions, Compound Assignment, and Mixed-Type Expressions

Module 3 — Operators and Expressions · Week 3 · Lecture 6 of 32 · 120 minutes Outcomes: CLO-2 · PF-3.3, PF-3.4 · LEARNING_OUTCOMES.md · Assignment 1 due

Learning objectives

  1. Predict the value and type of mixed-type expressions: int → double promotion, assignment-driven conversion, and truncation on double→int narrowing (PF-3.3).
  2. Convert deliberately with static_cast<int>(...) / static_cast<double>(...) and state where each is required in course code (PF-3.4).
  3. Rewrite update expressions with +=, -=, *=, /=, and pre/post ++/--, and predict expression values when increment placement matters (PF-3.4).

Prerequisites

L05 (arithmetic, truncation); L03 (assignment semantics).

Concept sequence

  1. Implicit conversions: the compiler's silent rewrites
  2. Promotion in mixed arithmetic (int op double → double)
  3. Assignment conversion: widening vs narrowing (truncation, no rounding)
  4. Explicit static_cast — course policy for narrowing
  5. Compound assignment & increment operators
  6. Pre- vs post-increment: value of the expression vs the variable

Teaching topics (detailed)

C++ examples required

FileRole
conversion_demo.cpp ✅promotion, narrowing, casts, char codes — 12 printed lines students predict first
(live) increment_trace.cpppre/post-increment state-table walk

Conceptual explanation (beginner-first)

Types must agree for an operation to happen — but C++ quietly converts values to make them agree. Mostly this is helpful: 3 + 0.5 becomes 3.5 because the 3 is promoted to a double. But conversions can also lose information: storing 5.7 into an int throws away the .7 — not by rounding, but by truncating toward zero. The danger is that the = form performs this narrowing silently; that is why the course standardizes: brace-init when you mean it, explicit static_cast when narrowing is truly intended.

The increment family (++, --) adds/subtracts one. The subtlety is the difference between the variable's new value and the expression's value: ++x increments first, then yields the new value; x++ yields the old value, then increments. In standalone statements there is no difference — which is why the course style says: use them standalone, and the subtlety stays out of your way.

Terminology and definitions

TermDefinition
Implicit conversionCompiler-inserted conversion to make types agree
PromotionSmaller type widened (int → double) — no data loss
NarrowingConversion that can lose data (double → int, truncation)
static_cast<T>(x)Explicit, searchable conversion — course-required for narrowing
Compound assignmentx += 5 ≡ x = x + 5 (also -= *= /= %=)
Increment ++ / decrement --Add/subtract 1 (prefix vs postfix forms)
Prefix vs postfix++x: increment then yield; x++: yield then increment
Truncation toward zero-3.9 → -3 (not −4); same rule as integer division

Syntax and C++ examples

double d{5};                          // promotion: 5 -> 5.0 (safe)
int truncated = 5.7;                  // = form: silent truncation -> 5
int dollars{static_cast<int>(19.99)}; // explicit, searchable -> 19
int back{static_cast<int>(-3.9)};     // -> -3 (toward zero)

char c{'A'};
int code{static_cast<int>(c)};        // 65 — chars are small numbers

int x{5};
x += 3;         // x = 8
x *= 2;         // x = 16
++x;            // x = 17 (standalone: prefix/postfix identical)
int old{x++};   // old = 17, x = 18 (postfix yields OLD value)
int neu{++x};   // x = 19 first, neu = 19 (prefix yields NEW value)

Line-by-line code explanation

examples/conversion_demo.cpp (predict each printed line first):

  1. 3 + 0.5 → 3.5: the int is promoted; the whole expression becomes double.
  2. double widened{5}; → prints 5 — widening never loses data, so braces allow it.
  3. int truncated = 5.7; → 5 — the = form silently truncates. The commented line above it (int narrowed{5.7};) is what would produce error: narrowing conversion — the brace shield.
  4. static_cast<int>(19.99) → 19 and static_cast<int>(-3.9) → -3 — truncation toward zero, not flooring.
  5. nine / 2.0 → 4.5 (promotion mid-expression), then wrapped in static_cast<int> → 4 — the two-step pipeline students must trace.
  6. static_cast<int>('A') → 65, static_cast<char>(66) → B — the char↔int dictionary that Module 11 builds on.
  7. bool flag = 3.9; → prints 1 — any nonzero value becomes true; note the braces would reject this narrowing (as intended).

Output prediction questions (with answers)

  1. int x = 9 / 2.0; — x? — 4 (9/2.0 is 4.5, then truncation on store).
  2. static_cast<int>(-3.9) — ? — -3 (toward zero).
  3. After int a{5}; int b{a++}; — a and b? — a=6, b=5 (postfix yields the old value).
  4. After int a{5}; int b{++a}; — ? — a=6, b=6.
  5. double half{7 / 2}; — half? — 3.0 — the division happened in ints FIRST; storing into a double is too late (the classic order-of-events question).

Common errors and debugging examples

ErrorSymptomFix
Rounding assumptionstatic_cast<int>(2.9) believed to be 3; it is 2Cast truncates; round explicitly if needed
Cast after the factdouble d{7 / 2}; → 3.0Make ONE operand double: 7 / 2.0
Silent narrowing via =Data loss with no diagnosticBrace-init; static_cast when intended
Two ++ on one variable in a statementUndefined behaviorOne modification per expression
x++ where ++x intended (in expressions)Off-by-one using the yielded valueStandalone style avoids it entirely

Common student misconceptions

Classroom demonstrations

  1. The two-line proof: compile int a{5.7}; (error) beside int b = 5.7; (silent 5) — the brace shield made visible.
  2. Pre/post state tables: trace int old{x++}; and int neu{++x}; on the board with columns x, yielded — the table IS the explanation.
  3. Character codes: print 'A' + 1 as char → 'B', seeding Module 11's letter arithmetic.

Guided student activities

Conversion carousel (20 min): 6 stations around the room, each with a 3-line program and a prediction card; students rotate, commit predictions, then the station answer is revealed; debrief the two most-missed stations.

Practice problems

Summary

Mixed-type expressions promote; assignment may narrow silently — which is why the course requires braces (which reject narrowing) and explicit static_cast (which documents it). Truncation is toward zero. Compound assignment updates in place; pre/post increment differ only in the value the expression yields — keep them standalone and the trap vanishes. Next (Module 4): programs that choose — if, comparisons, and logical operators.

Exit ticket / formative assessment

  1. int x = 9 / 2.0; — value? type of the right-hand side before the assignment conversion?
  2. static_cast<int>(-3.9) = ?
  3. After int a{5}; int b{a++}; what are a and b?

Estimated time allocation (120 min)

SegmentMinutes
Recall (division quiz) + silent conversions motivation10
Promotion + assignment conversion + static_cast policy35
Break10
Compound assignment + pre/post increment with state tables30
Conversion carousel activity20
Assignment 1 hand-in reminder + exit ticket15
Programming Fundamentals Using C++ · C++17 · 16 weeksBack to top ↑