CSCI 159: Fall 2025 Final Exam
Sections F25N01-F25N02 (Dr. Wessels)


Question 1: Write a complete program [10]

Write a complete C++ program that:


Question 2: Functions and parameters [10]

Write a C++ function that meets the following specifications:
Trivia: linux time is measured in seconds since Jan. 1, 1970, and if stored as a 32-bit int the clock will hit its maximum possible value on Jan. 19, 2038. While most linux systems have switched to a 64-bit time, the resulting clock overflow issues on older 32-bit systems have raised comparisons to the y2k fears of the late 1990's.

Question 3: Recursion [10]

First: complete the recursive C++ function below to meet its specifications,
Second: explain why your implementation will work correctly.

// reads user input one character at a time (including whitespace)
//     until it sees the 'stopping' character
// then displays all the characters in reverse order
//
// e.g. if the call was readAndReverse('x') and the user typed "blah foo ickx"
//      then the output would be "xkci oof halb"
//
// RESTRICTION: the function cannot use arrays or strings to hold data (only single chars)
void readAndReverse(char stopping);

Hint: have the function read one char and store it,
if it's the stopping char then print it
otherwise make a recursive call and then print the char you just read


Question 4: Loops [10]

As precisely as possible, show the output that would result from running the following code segment, assuming it ran within a valid C++ program.
char first = '*';
char second = '?';
for (int r = 0; r < 4; r++) {
    cout << "trial " << r << ": ";
    for (int c = 0; c < 7; c++) {
        if (c < r) {
           cout << first;
        } else {
           cout << second;
        }
    }
    cout << endl;
}

Question 5: Scopes and nesting [10]

The program below utilizes a variety of layers of scopes. As precisely as possible, show the output that would result from running the compiled program.
#include <iostream>
using namespace std;

int x = 1;
int y = 0;

void f(int &x, int y);
int g(int &a);

int main()
{
   int x = 4;
   int y = 1;
   f(y, g(x));
   cout << "In main: x is " << x << ", y is " << y << endl;
}

void f(int &x, int y)
{
   x = y;
   y = x;
   cout << "In f: x is " << x << ", y is " << y << endl;
}

int g(int &a)
{
   a = a + x;
   cout << "In g: a is " << a << ", x is " << x << endl;
   return a;
}


Question 6: Arrays (and null terminators) [10]

Complete the two functions described below so that they each meet their specifications.
// copy the first N values from source into dest, but in reverse order
// (i.e. element N-1 from source goes into dest 0, element N-2 goes into dest 1, etc)
void copyreverse(float dest[], float source[], int N);

// assuming str1 and str2 are both null terminated character arrays,
// returns the length of the longer of the two
int larger(char str1[], char str2[]);

Question 7: Sorting and searching [10]

(i) Describe the effect the function below would have on an array of floats.
(Assume swap correctly exchanges the values of two floats and fabs returns the absolute value of a float.)
void dostuff(float arr[], int N)
{
   if (N < 2) {
      return;
   }
   int i = 1;
   do {
      int j = 1;
      while (j < N) {
         if (fabs(arr[j-1]) > fabs(arr[j])) {
            swap(arr[j-1], arr[j]);
         }
         j++;
      }
      i++;
   } while (i < N);
}

(ii) If we had a binary search function that expects to be passed an array of floats sorted in non-decreasing order, but is actually passed an array processed by the function above, under what conditions (if any) would binary search work correctly on the array and why?


Question 8: Arrays of structs [10]

(i) Provide the definition a struct with the following specifications: (ii) Based on your answer to (i), provide a function with the following specifications: (iii) Based on your answers to (i) and (ii), write a code segment that meets the following specifications:

Question 9: Pointers and dynamic allocation [10]

(i) Assuming all other relevant functions have already been implemented, rewrite just the main routine below to use a pointer, new, and delete to appropriately dynamically allocate and deallocate the dataValues array to be exactly the neededSize, rather than the fixed MaxSize array currently used. All other behaviour in main should remain exactly the same.
int main()
{
   const int MaxSize = 1000;
   float dataValues[MaxSize];
   int neededSize = getDesiredSize();
   for (int i = 0; i < neededSize; i++) {
      fill(dataValues[i]);
   }
   for (int i = neededSize-1; i >= 0; i--) {
      process(dataValues[i]);
   }
   for (int i = 0; i < neededSize; i++) {
      display(dataValues[i]);
   }
}
(ii) Given the struct definition and function prototype/specifications below, complete the implementation of the function.
// struct definiton
struct Marks {
   string studentName;  // student's name
   int numMarks; // number of assignments completed
   float allMarks[MaxMarks]; // marks for completed assignments
};

// after ensuring the pointer to the Marks struct isn't null,
// prints the students name, number of assignments completed,
//    and their marks for each of the completed assignments
void printMarks(Marks* stmarks)


That's all, good luck with the rest of your exams and have a good winter break!