Command Palette

Search for a command to run...

MTH 4300

MTH 4300 Midterm 1 Practice

This practice exam has 5 tracing questions, 5 debugging questions, and 5 programming questions.

Give each question an honest shot. Use an AI tool to check your answers afterwards.

Tracing

For each question, write the exact output. Include spaces and line breaks.

T1. Types and operators

#include <iostream>

int main() {
    int a = 7;
    int b = 2;
    double x = a / b;
    double y = static_cast<double>(a) / b;
    std::cout << x << " " << y << '\n';

    int c = a++;
    int d = ++b;
    std::cout << a << " " << b << " " << c << " " << d << '\n';
    std::cout << (a > 7 && b < 3) << '\n';
}

T2. Conditionals and loops

#include <iostream>

int main() {
    int total = 0;
    for (int i = 1; i <= 5; ++i) {
        if (i % 2 == 0) {
            total += i;
        } else if (i > 3) {
            total -= i;
        } else {
            total += 1;
        }
        std::cout << total << " ";
    }
    std::cout << '\n';

    int n = 3;
    while (n > 0) {
        std::cout << n;
        --n;
    }
    std::cout << '\n';
}

T3. Values, references, and pointers

Track a and b after each call.

#include <iostream>

void change(int value, int& ref, int* ptr) {
    value += 10;
    ref += value;
    *ptr -= 2;
    std::cout << value << " " << ref << " " << *ptr << '\n';
}

int main() {
    int a = 4;
    int b = 1;
    change(a, b, &a);
    std::cout << a << " " << b << '\n';
    change(b, a, &b);
    std::cout << a << " " << b << '\n';
}

T4. Arrays and dynamic allocation

#include <iostream>

int main() {
    int* values = new int[4]{2, 4, 6, 8};
    int* p = values + 1;
    *(p + 1) = *p + values[3];
    --p;
    *p += values[2];

    for (int i = 0; i < 4; ++i) {
        std::cout << values[i] << " ";
    }
    std::cout << '\n' << (values[2] - values[0]) << '\n';
    delete[] values;
}

T5. Vectors, algorithms, and recursion

Show the calls and return values for sumFirst(v, 3).

#include <algorithm>
#include <iostream>
#include <vector>

int sumFirst(const std::vector<int>& v, int n) {
    if (n == 0) return 0;
    return v[n - 1] + sumFirst(v, n - 1);
}

int main() {
    std::vector<int> v{5, 2, 7, 4};
    std::sort(v.begin(), v.end());
    int count = std::count_if(v.begin(), v.end(), [](int x) {
        return x % 2 == 0;
    });
    std::cout << count << " " << sumFirst(v, 3) << '\n';
    for (int x : v) std::cout << x << " ";
    std::cout << '\n';
}

Debugging

Each program or function has two independent bugs. For each bug, identify the faulty expression or statement, explain the failure, and give a correction. Keep the stated behavior and function signature.

D1. Average of positive inputs

meanPositive should return the mean of the positive values in data. Return 0.0 if there are none. The input in main should produce 2.5.

#include <iostream>
#include <vector>

double meanPositive(const std::vector<int>& data) {
    int total = 0;
    int count = 0;
    for (int x : data) {
        if (x >= 0) {
            total += x;
            ++count;
        }
    }
    if (count == 0) return 0.0;
    return total / count;
}

int main() {
    std::cout << meanPositive({-5, 2, 3}) << '\n';
}

D2. Pointer parameters

addToBoth should add step to each non-null target. The two arguments may point to the same integer. The call shown should leave x equal to 11.

#include <iostream>

void addToBoth(int* first, int* second, int step) {
    if (first != nullptr) first += step;
    *second += step;
}

int main() {
    int x = 5;
    addToBoth(&x, &x, 3);
    std::cout << x << '\n';
}

D3. Dynamic arrays

makeSquares(n) should return a new array containing 0², 1², ..., (n-1)². The caller owns the array. Assume n > 0.

#include <iostream>

int* makeSquares(int n) {
    int* result = new int[n];
    for (int i = 0; i <= n; ++i) {
        result[i] = i * i;
    }
    return result;
}

int main() {
    int* squares = makeSquares(3);
    std::cout << squares[0] << " " << squares[1] << " " << squares[2] << '\n';
    delete squares;
}

printFirstAbove should print the first value strictly greater than limit, or none if no such value exists. The sample should print 9.

#include <algorithm>
#include <iostream>
#include <vector>

void printFirstAbove(const std::vector<int>& values, int limit) {
    auto it = std::find_if(values.begin(), values.end(), [limit](int x) {
        return x >= limit;
    });
    std::cout << *it << '\n';
}

int main() {
    printFirstAbove({2, 5, 9}, 5);
}

contains should search the half-open interval [lo, hi) and work for an empty vector. Both sample calls should print 1.

#include <iostream>
#include <vector>

bool contains(const std::vector<int>& values, int lo, int hi, int target) {
    if (lo == hi) return true;
    if (values[lo] == target) return true;
    return contains(values, lo + 2, hi, target);
}

int main() {
    std::vector<int> values{4, 7, 9};
    std::cout << contains(values, 0, 3, 7) << '\n';
    std::cout << !contains(values, 0, 0, 7) << '\n';
}

Programming

Write each function from its signature. You may add required standard headers. State any loop invariant or recursive base case you rely on. Follow the limits in each question.

P1. Sum of multiples

int sumMultiples(int first, int last, int divisor);

Return the sum of all integers in the inclusive interval [first, last] that are divisible by divisor. Assume divisor > 0. If first > last, return 0. Use a loop. Examples: sumMultiples(1, 10, 3) == 18 and sumMultiples(5, 4, 2) == 0.

P2. Update through a pointer

bool increaseIfBelow(int* value, int limit, int amount);

If value is non-null and *value < limit, add amount to *value and return true. Otherwise leave everything unchanged and return false. amount may be negative. Do not allocate memory. Examples: starting at 4, increaseIfBelow(&x, 5, 3) changes x to 7 and returns true; calling it with nullptr returns false.

P3. Reverse into a new array

int* reversedCopy(const int* source, int n);

Assume n >= 0 and source points to at least n integers when n > 0. Return a dynamically allocated array of length n with the elements in reverse order. The caller frees the result with delete[]. Do not modify source and do not use std::vector. For n == 0, returning an array allocated with new int[0] is allowed. Example: {2, 5, 8} becomes {8, 5, 2}.

P4. Count values in a range

int countInRange(const std::vector<int>& values, int low, int high);

Return the number of values in the inclusive interval [low, high]. Use std::count_if and a lambda that captures the bounds. If low > high, return 0. Example: countInRange({1, 3, 3, 7}, 2, 3) == 2.

P5. Recursive count

int countMatches(const std::vector<int>& values, int target, int index);

Return the number of occurrences of target from index through the end of the vector. Assume 0 <= index <= values.size(). Use recursion with no loops or algorithms. Examples: countMatches({2, 1, 2, 2}, 2, 0) == 3 and countMatches({2, 1, 2, 2}, 2, 2) == 2.