Skip to content

Bank 1 — Mindset and compilation

Eleven exercises on how a C++ program becomes a running process, and on the difference between a thing and a bag of fields. Module 1. Levels L1–L6.

Solutions are in Solutions and answers; nudges are in Hints. Attempt first.


Exercises

E01 — Where does each mistake fail? L1 concept

C++ builds a program in three stages: preprocessing, compilation and linking. For each of the four mistakes below, say which stage reports it, and what the message is about.

  1. A missing semicolon.
  2. A missing #include <iostream> used only for std::cout.
  3. A function that is declared and called but never defined.
  4. A statement that dereferences a null pointer at run time.

Task. One sentence per mistake. For (4), name the stage and then say why no compiler stage could have caught it.


E02 — Value or reference? L2 predict

Write the exact output before running it.

#include <iostream>

void bumpByValue(int n)  { n = n + 1; }
void bumpByRef(int& n)   { n = n + 1; }

int main() {
    int a = 10;
    bumpByValue(a);
    std::cout << a << '\n';
    bumpByRef(a);
    std::cout << a << '\n';
}

Task. Two lines of output, and a one-sentence explanation of the difference. (Why can the two functions not both be named bump and called with a?)


E03 — Fill in the totals L2 complete

The program below prints the total of an array of prices and the total after a 10% discount. Two lines are missing.

#include <iostream>

double total(const double* prices, int count) {
    double sum = 0.0;
    for (int i = 0; i < count; ++i) {
        sum += prices[i];
    }
    return sum;
}

int main() {
    const int n = 5;
    double prices[n] = { 4.50, 12.00, 3.25, 8.00, 1.75 };

    double before = total(prices, n);
    // TODO (1): compute `after` as 90% of `before`

    std::cout << "before: " << before << '\n';
    // TODO (2): print the line "after:  <value>"
}

Task. Supply the two missing statements so the program prints the total before and after the discount. State what the two totals are.


E04 — The marks report L2 trace scenario

A classroom tool prints the average mark of a class. Work out the output by hand, line by line.

#include <iostream>

int main() {
    int marks[5] = { 62, 75, 81, 48, 90 };
    int sum = 0;
    for (int i = 0; i < 5; ++i) {
        sum += marks[i];
    }
    double average = sum / 5;
    std::cout << "sum: " << sum << '\n';
    std::cout << "average: " << average << '\n';
    return 0;
}

Task. Give the two printed lines, then say whether the average is what a teacher would expect for a 5-mark class averaging 71.2, and why.


E05 — It will not build L2 debug scenario

A student's first program for a "course roster" tool does not compile.

#include <string>

int main() {
    std::string name = "Ayesha";
    std::cout << "Roster entry: " << name << '\n';
    return 0;
}

Task. State the cause, then fix it in the smallest way that still leaves the program readable. Do not guess the compiler message — reproduce it with your own toolchain and read it.


E06 — Add a column, count the cost L3 modify scenario

An inventory report stores each product as three parallel arrays:

#include <iostream>
#include <string>

int main() {
    std::string names[3]  = { "Nails", "Screws", "Bolts" };
    int         stock[3]  = { 500, 1200, 300 };
    double      price[3]  = { 0.02, 0.05, 0.08 };

    for (int i = 0; i < 3; ++i) {
        std::cout << names[i] << ": " << stock[i]
                  << " at " << price[i] << '\n';
    }
    return 0;
}

Task. Add a fourth column, supplier (a std::string), with one supplier per product, and print it. Then write down how many lines you changed and why a fourth parallel array is a warning sign rather than just a small edit.


E07 — Integer arithmetic L2 predict

#include <iostream>

int main() {
    int  a = 7;
    int  b = 2;
    double c = 7 / 2;
    double d = 7.0 / 2;
    std::cout << c << '\n';
    std::cout << d << '\n';
    std::cout << a / b << '\n';
    return 0;
}

Task. Three lines, exactly as printed. Explain, in one sentence, why c and d differ even though both are double.


E08 — Where can this be corrupted? L4 analyze

Read the procedural catalogue below. List every way a later programmer could make it report the wrong thing without the compiler objecting.

#include <iostream>
#include <string>

std::string titles[4]      = { "Dune", "Emma", "Ilium", "Neuromancer" };
bool        onLoan[4]      = { false, false, false, false };
int         borrowedCount  = 0;

bool lend(int index) {
    if (index < 0 || index >= 4) return false;
    if (onLoan[index]) return false;
    onLoan[index] = true;
    borrowedCount++;
    return true;
}

int main() {
    lend(1);
    lend(3);
    std::cout << "borrowed: " << borrowedCount << '\n';
    return 0;
}

Task. At least four distinct fragilities, each naming the specific line or identifier involved, and for each one: would anything in this program detect it?


E09 — Off by one L3 debug

A scoreboard is supposed to add up the points of all five rounds, but it reports a total that is a few points short.

#include <iostream>

int main() {
    int points[5] = { 10, 20, 30, 40, 50 };
    int total = 0;
    for (int i = 1; i < 5; ++i) {
        total += points[i];
    }
    std::cout << "total: " << total << '\n';
    return 0;
}

Task. (a) Work out the wrong total it prints. (b) State the defect in one sentence. (c) Fix it, and give the correct total.


E10 — Model a club L5 design scenario

A student club tracks members, events and attendance. Members sign up for events; after each event the club records who attended.

Task. On paper (no syntax), for each candidate type write:

  1. its responsibility, in one sentence with no "and";
  2. the data it holds;
  3. the operations it offers.

Then name one thing you deliberately did not make a type, and say why.

How you will be judged. On the exclusions as much as the inclusions. A design in which everything becomes a type has made no decisions.


E11 — Before you reach for classes L6 refactor scenario

The club treasurer keeps attendance in a growing program built from the arrays in E06's style. A new requirement arrives: "each member can attend many events, and we want to ask how many events a given member attended."

Task. In one page, before writing any code:

  1. State what the four or five parallel arrays would need to become, and why the current shape fights the new question.
  2. Propose the types you would introduce, with their responsibilities in one line each.
  3. Name one risk of your refactor — something that could break that currently works.
  4. Argue the other side: give one reason to keep the arrays and add a fifth function instead, then say why you rejected it (or accepted it).

Success. A reader can see both designs and your reason for the one you chose. There is no single correct answer; there is a defended one.


Next topic: Classes and encapsulation · Hints: hints.md · Solutions: solutions.md