Final Practice Exam B

25 fresh questions · 8 sections · 90 minutes · closed book. A different balance from Final A: more write-the-code and diagnose-the-bug items, fewer pure recall. Sit it only after Final A’s post-exam worksheet is done — that’s when a second measurement means something.

← Final Exam A · Hub

Instructions

Same rules as Final A: one sitting, paper answers, one key at the bottom. Section weights below.

Section Topic Questions Weight
A Concepts & vocabulary Q1–Q3 12
B I/O, strings, files Q4–Q7 16
C Conditions & validation Q8–Q10 12
D Loops: tracing & writing Q11–Q14 16
E Functions: writing & diagnosing Q15–Q17 12
F Collections & algorithms Q18–Q20 12
G Memory & pointers Q21–Q22 8
H OOP & design Q23–Q25 12

Section A — Concepts (Q1–Q3)

Q1. [Easy] In two sentences each: what the compiler does, and what the linker’s job is in a one-file program (hint: think main and <iostream>).

Q2. [Medium] Give the type and value of each:

int a = 5 % 2;
double b = 5 / 2;
double c = (double)5 / 2;
char d = 'A' + 1;

Q3. [Medium] A variable is declared inside a function and another with the same name outside it. In two sentences: which one does a statement inside the function see, and what is this called?

Section B — I/O, strings, files (Q4–Q7)

Q4. [Medium] Write the exact output:

string first = "Data", second = "Science";
cout << second << " of " << first << "\n";
cout << first + "-" + second;

Q5. [Medium] A program must read a full address line (“12-B, Gulberg III, Lahore”) after reading an integer house number. Write the two input statements in order, with the fix that makes them cooperate.

Q6. [Medium] What does this print? (data.txt holds one line: b 2 a 1)

ifstream in("data.txt");
string s; int n;
while (in >> s >> n) cout << n << s << " ";

Q7. [Hard] Write a complete loop (declarations included) that counts how many lines of notes.txt are longer than 40 characters, and prints the count. Handle a missing file by printing missing and stopping.

Section C — Conditions & validation (Q8–Q10)

Q8. [Medium] Write the condition: rush is true when hour (0–23) is strictly between 7 and 9, or strictly between 17 and 19.

Q9. [Medium] What does this print for pin = 1234? And for pin = 0?

if (pin >= 1000 && pin <= 9999) cout << "valid";
else                            cout << "invalid";

Q10. [Hard] This ladder misclassifies: a mark of exactly 50 prints FAIL but the spec says pass-at-50. Identify the two broken comparisons and rewrite the ladder.

if (marks > 50)       cout << "PASS";
else if (marks > 70)  cout << "MERIT";
else if (marks > 85)  cout << "DISTINCTION";
else                  cout << "FAIL";

Section D — Loops (Q11–Q14)

Q11. [Medium] What does this print?

int p = 1;
for (int i = 1; i <= 5; i++)
    if (i % 2 == 1) p *= i;
cout << p;

Q12. [Medium] What does this print?

int x = 100;
int steps = 0;
while (x > 1) {
    x = x / 2;
    steps++;
}
cout << x << " " << steps;

Q13. [Hard] Write a complete loop (no functions needed) that prints this exact shape for the fixed height 4:

1
22
333
4444

Q14. [Hard] The loop below should sum the digits of every number the user enters until 0, but prints wrong results. Diagnose the bug (1 mark) and write the corrected loop (1.5 marks):

int n, total = 0;
while (cin >> n && n != 0) {
    while (n > 0) {
        total = n % 10;
        n /= 10;
    }
}
cout << total;

Section E — Functions (Q15–Q17)

Q15. [Medium] What does this print?

int g = 5;
void bump(int n) { n += g; }
int main() {
    int v = 10;
    bump(v);
    cout << v;
}

Q16. [Medium] Write the prototype and the definition for long long pow2(int e) — returns 2^e by a loop, for e in 0–62 — and one call printing pow2(10).

Q17. [Hard] This function compiles but never changes the caller’s doubles. Name the defect (0.5) and write the corrected signature line + body (1.5):

void normalize(double x) {
    x = x / 100.0;
}

Section F — Collections & algorithms (Q18–Q20)

Q18. [Medium] What does this print?

vector<string> v = {"kiwi", "apple", "fig"};
string shortest = v[0];
for (size_t i = 1; i < v.size(); i++)
    if (v[i].size() < shortest.size()) shortest = v[i];
cout << shortest;

Q19. [Medium] One pass of selection sort (ascending) is applied to {6, 2, 8, 4}. Write the array afterwards, and state how many swaps happened.

Q20. [Hard] Write a complete function int countBelow(const vector<int>& v, int cut) (declarations included) that returns how many elements are strictly below cut. Full marks for the empty-vector case.

Section G — Memory & pointers (Q21–Q22)

Q21. [Medium] What does this print?

int vals[4] = {9, 8, 7, 6};
int* p = vals;
p++;
cout << *p << *(p + 2);

Q22. [Hard] This program has exactly two memory defects. Name each (0.5 each) and write the corrected line(s) (1 each):

int main() {
    int* a = new int[10];
    int* b = new int[10];
    for (int i = 0; i < 10; i++) { a[i] = i; b[i] = i * 2; }
    delete[] a;
    return 0;
}

Section H — OOP & design (Q23–Q25)

Q23. [Medium] What does this print?

class Light {
    bool on = false;
public:
    void toggle() { on = !on; }
    string state() const { return on ? "ON" : "OFF"; }
};
int main() {
    Light l;
    l.toggle(); l.toggle(); l.toggle();
    cout << l.state();
}

Q24. [Hard] Design in words + signatures (no full bodies): a class Temperature holding a double celsius, with (a) a constructor that rejects values below −273.15 by storing 0 and remembering the rejection, or throws invalid_argument — choose one, justify in one sentence; (b) a toFahrenheit() const; (c) operator<< for printing 25C. (1 mark per part, 1 for the justification.)

Q25. [Hard] Two sentences: why does the course prefer composition (has-a) by default, and name one concrete situation from the course where inheritance (is-a) was the right call.


Final Exam B — Answer key (open only after the full 90 minutes)

Section A

Q1. Compiler: translates the whole source file into machine code / object form, catching grammar errors first. Linker: connects the object code to the standard library’s compiled implementations (cout machinery) and to main as the entry point, producing the executable.

Q2. a = int 1 · b = double 2 (integer division happened first — the result is then converted) · c = double 2.5 (the cast promotes before dividing) · d = char ‘B’ (‘A’ + 1 promotes to int 66, converted back to char).

Q3. The statement sees the local — the inner declaration shadows the outer within the function’s scope. This is name shadowing; ::name reaches the outer/global one explicitly.

Section B

Q4. Science of Data / Data-Science — exact strings, one newline after the first line.

Q5.

int house;
cin >> house;
cin.ignore();            // eat the newline left by >>
string address;
getline(cin, address);

Q6. 2b 1a — pairs stream as (s,n); output concatenates n then s per pass, space-separated.

Q7. Reference:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    ifstream in("notes.txt");
    if (!in) { cout << "missing\n"; return 0; }
    string line;
    int count = 0;
    while (getline(in, line))
        if (line.size() > 40) count++;
    cout << count << "\n";
    return 0;
}

(Marks: open+guard 0.5, getline loop 0.5, size test 0.5, count+print 0.5.)

Section C

Q8. (hour > 7 && hour < 9) || (hour > 17 && hour < 19) — “strictly between” excludes the endpoints; the two windows join with ||.

Q9. 1234 → valid; 0 → invalid (0 fails the ≥1000 side; the guard correctly rejects absurd pins).

Q10. Two defects: (1) > 50 must be >= 50 for pass-at-50; (2) the ladder’s thresholds are unreachable in order — any mark > 70 is caught by the first branch (since > 85 is also > 50… specifically: after fixing (1), MERIT and DISTINCTION can never fire because the first branch swallows them). Corrected:

if (marks > 85)       cout << "DISTINCTION";
else if (marks >= 70) cout << "MERIT";
else if (marks >= 50) cout << "PASS";
else                  cout << "FAIL";

(Highest threshold first; boundaries chosen to match the spec.)

Section D

Q11. 15 — odd i values 1, 3, 5 multiplied: 1·3·5.

Q12. 1 6 — 100→50→25→12→6→3→1: six halvings, x ends at 1. (Integer division: 12/2=6, 6/2=3, 3/2=1.)

Q13. Reference:

for (int row = 1; row <= 4; row++) {
    for (int k = 1; k <= row; k++)
        cout << row;
    cout << "\n";
}

(Marks: outer rows 0.5, dependent inner count 0.5, newline 0.5, exact digits 0.5.)

Q14. Defect: total = n % 10; assigns, discarding earlier digits — only the last digit of the last number survives. Corrected:

int n, total = 0;
while (cin >> n && n != 0) {
    while (n > 0) {
        total += n % 10;   // accumulate, not assign
        n /= 10;
    }
}
cout << total;

Section E

Q15. 10 — n is a copy; n += g changed the copy. The global g was read, but no write reached v.

Q16.

long long pow2(int e);                      // prototype

long long pow2(int e) {                     // definition
    long long r = 1;
    for (int i = 0; i < e; i++) r *= 2;
    return r;
}
// call:
cout << pow2(10);   // 1024

(Marks: prototype 0.5, correct loop and type 0.5, return 0.5, call 0.5.)

Q17. Defect: pass-by-value — the function divides its own copy. Corrected:

void normalize(double& x) {
    x = x / 100.0;
}

(The & is the whole repair; the body was already correct.)

Section F

Q18. fig — shortest-wins scan: kiwi(4) → apple(5) no → fig(3) yes.

Q19. {2, 6, 8, 4} — pass 1 selects min (2) and swaps with slot 0: exactly 1 swap (selection does at most one per pass).

Q20. Reference:

#include <vector>
using namespace std;

int countBelow(const vector<int>& v, int cut) {
    int count = 0;
    for (size_t i = 0; i < v.size(); i++)
        if (v[i] < cut) count++;
    return count;
}

Empty vector: the loop body never runs → returns 0 — correct without a special case. (Range-for version equally correct; marks: signature+const& 0.5, loop 0.5, strict < 0.5, empty-case reasoning 0.5.)

Section G

Q21. 87 — p++ moved to index 1 (8); p+2 is index 3 (6).

Q22. (1) Leak: b is never freed. Fix: delete[] b; before return. (2) (Half-credit framing) The return 0 path is fine here because both deletes precede it — but a’s delete is present while b’s is missing: the single required fix is delete[] b;. Full marks: name the missing delete (0.5), add delete[] b; (1). If you also reordered deletes to release both on every path (defensive restructuring), that earns the second mark.

Section H

Q23. ON — three toggles: ON→OFF→ON. Odd toggles end ON.

Q24. Reference choice: throw invalid_argument — one sentence: a temperature below absolute zero is not a temperature, so the object should never exist in that state, and an exception makes the failure loud at the construction site rather than silent in the data.

class Temperature {
    double c;
public:
    Temperature(double celsius) {
        if (celsius < -273.15) throw invalid_argument("below absolute zero");
        c = celsius;
    }
    double toFahrenheit() const { return c * 9.0 / 5.0 + 32.0; }
};
ostream& operator<<(ostream& os, const Temperature& t) {
    return os << t.toFahrenheit() << "F-from-" << 0;   // see note
}

(Practical note: printing 25C needs the celsius value — either a getCelsius() const accessor used inside operator«, or friend. The marked skills are the guard choice + justification, the const conversion method, and the operator’s stream-in/stream-out shape. The storing-0 alternative earns full marks only with an honest one-sentence cost: the object then lies about being a temperature.)

Q25. Composition couples less: the part can be swapped, tested, and reused without dragging the whole hierarchy along, and has-a describes most real relationships. Inheritance earned its place in the course’s shape hierarchies (Circle/Rectangle behind a Shape interface): genuinely is-a, shared interface, and the collection needed to treat them uniformly through one base type.


Scoring guide

Raw /25 % Verdict Action
23–25 ≥90 Ready The course is yours. Move to the capstone build with confidence.
18–22 70–89 Almost Target the sections below 70%; retake B in 3+ days — or alternate with A for a fresh form.
≤ 17 <70 Not yet Rebuild from the flagged units’ modules; A-and-B both wait.

Section health check:

Section Topic to revisit
A Getting Started · Cpp foundations
B Getting Started · Strings · Files
C Decisions module
D Repetition module
E Functions module
F Arrays · Algorithms · STL module
G Pointers module
H OOP module · Robustness module

Compare with Final A: any section weaker in both exams is a true gap — schedule it. Sections strong in A but weak in B (or vice versa) are usually question-style effects, not gaps.

← Final Exam A · Hub