Module 1 — Exercises¶
Every exercise states its level and its success criterion, so you can tell whether you succeeded without reading a solution. Attempt before you check: reading a solution produces recognition, and recognition is not the skill being tested.
Warm-up [L1 Understand]¶
W1 — name the stages¶
Task. Write one sentence each for preprocessing, compilation and linking, then say which stage fails for each of these three mistakes:
- a missing semicolon
- a function declared and never defined
- reading through a null pointer
Success looks like. Five sentences, and no jargon you cannot define. The third mistake's answer should not name a stage at all — say why.
Stuck? Section 1 and 2 of Concepts.
W2 — predict, then check¶
Task. For the program below, write down the exact output before running it.
#include <iostream>
void doubleIt(int n) { n = n * 2; }
void doubleItRef(int& n) { n = n * 2; }
int main() {
int a = 4;
doubleIt(a);
std::cout << a << '\n';
doubleItRef(a);
std::cout << a << '\n';
}
Success looks like. Two lines, both correct, with a one-sentence reason for the difference. If your prediction was wrong, the reason matters more than the numbers.
Stuck? Section 8 of Concepts, and
examples/module-01/02-values-references-pointers/main.cpp.
Core [L2 Apply] · [L3 Modify] · [L4 Analyze]¶
C1 — write a small program from a blank file [L2 Apply]¶
Task. Write and run a program that:
- declares an array of five prices;
- writes a function
double total(const double* prices, int count)that sums them; - writes a function
void applyDiscount(double* prices, int count, double factor)that multiplies each price; - prints the total before and after a discount of 0.9.
Success looks like. Correct totals for the given data, plus: an empty array (total 0), and a single element. Builds with no warnings using the course's command.
Note. One of the two functions takes a double* and one takes const double*.
Explain in a comment why the first needs the non-const pointer.
C2 — a program that is deliberately broken [L3 Modify]¶
Task. Take a working program of your own and break it four ways, predicting each error before you compile:
- delete a semicolon
- delete an
#include - misspell an identifier
- remove
mainentirely
Success looks like. Eight lines: four predictions, four outcomes — and each outcome matched to the prediction or explained. At least one prediction should be wrong; if all four were right, you already know this material and should move to C4.
Stuck? Debugging.
C3 — add a field, and count the cost [L3 Modify] (deliberately tedious)¶
Task. Take examples/module-01/01-procedural-baseline/main.cpp and add a
publicationYear field to every item. Then do the same to
examples/module-01/03-first-class/main.cpp.
Success looks like. Both programs work, showing the year in the catalogue listing, and a written count: how many lines changed in each version, and how many call sites. The two numbers are the exercise.
Why it is tedious on purpose. The cost of a change is a fact you should measure once, by hand, rather than take on trust from a lecture.
C4 — find the fragilities [L4 Analyze]¶
Task. Read examples/module-01/01-procedural-baseline/main.cpp and list every
way a future programmer could corrupt the catalogue's data without the compiler
objecting. For each, cite the specific line or function.
Success looks like. At least four distinct fragilities, each naming a line, and for each one: whether anything in the program would detect it.
Full credit includes the one that is not about the arrays at all — the fact that
lend() reports two different failures with the same false.
Challenge [L4 Analyze] · [L5 Design]¶
X1 — design on paper, without syntax [L5 Design]¶
Task. A student club tracks members, events and attendance. For each candidate type, write: its responsibility in one sentence, the data it needs, and the operations it offers. Then name one thing you deliberately did not make a type, and why.
Success looks like. Every responsibility fits in one sentence without "and"; at least one defensible negative decision.
How you will be judged. On the exclusions as much as the inclusions. A design in which everything becomes a type has not made any decisions.
X2 — the rules nobody wrote down [L4 Analyze]¶
Task. Take a 100–200 line program you have written before (from another course, or an earlier attempt at this one) and list every rule it enforces implicitly — "the count is never negative", "these two arrays stay in step". For each rule, state where it is enforced: one place, several, or nowhere.
Success looks like. At least five rules. For each: the line(s) that enforce it, and what would happen if a new function forgot the rule.
Stretch (optional)¶
- S1 — "what changes if…" Suppose the catalogue must hold 10,000 items instead of four. In the procedural version, what breaks first — correctness or speed? In the class version, what breaks? Write three sentences before you change any code.
- S2 Find any
using namespace std;in code you have written before, remove it, and record every error the removal produces. The errors are the point: they show you which library names you had been taking for granted.
Solutions¶
Reference programs live in examples/module-01/. Exercise C1 has no published
solution on purpose: it is the smallest program in the module, and a published
version would be read rather than written.
For C3 and C4, compare your count and your list with the discussion in
Concepts §4 and the reflection guidance at the end of
examples/labs/lab-01/solution/main.cpp.
Next: Lab 1 — the deliberate baseline, and the reflection that makes it useful.