CSCI 159: Fall 2025 Final Exam
Sections F25N01-F25N02 (Dr. Wessels)
- You have 3 hours to complete the exam (1:00-4:00)
- There are 9 questions on the exam worth 10 marks each.
Your best 8 marks will be recorded out of a total of 80 marks.
- Answer in the exam booklets provided, extra booklets are available if needed. Be sure
to clearly number each of your answers in the booklet.
- The exam is closed book, closed notes, no calculators, phones, or other electronic aids
of any form may be used during the exam, but you are permitted one double-sided 8.5x11" sheet
of reference notes ("cheatsheet").
- The use of ear plugs/protection is permitted, but NOT the use of
headphones or headsets (with or without attached devices).
- Be sure to check your exam to make sure all 9 questions are included.
Question 1: Write a complete program [10]
Write a complete C++ program that:
- Starts by telling the user it wants to know their favorite date between the start of year 2000
and the end of year 2025:
- First gets them to enter the year as an integer 2000-2025,
- then gets the month as an integer 1-12,
- finally gets the day as an integer 1-31.
Each of the values should be stored in an appropriate variable.
- Do not check for non-integer input, but do check for out of range
integers (e.g. month < 1 or > 12). If an error is detected in a field then use
the smallest valid value as a default (2000, 1, 1 respectively). Do not get
them to try again.
- Display the resulting value in the form month/day/year with two digits each
for the month and day and four digits for the year, e.g. 12/05/2023.
Question 2: Functions and parameters [10]
Write a C++ function that meets the following specifications:
- The function is called epochalypse: it takes one pass-by-reference int parameter
named daysleft and returns a float.
- It gets the current linux time in seconds (which can be obtained using the call time(NULL)).
- It computes the number of seconds left before 32-bit linux clocks overflow by
subtracting the current time from INT_MAX, and stores the computed value in
timeleft.
- It computes the number of daysleft by dividing the seconds left by the number of
seconds in a day (24*60*60), storing the result in the passed parameter.
- It returns the number of seconds left.
| 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:
(Note: the struct will be used to represent information about a rectangle in the x-y plane.)
- The struct is named InfoBox
- It has one string field, named BoxName
- It has four float fields, named top, bottom, left, and right
(top and bottom get used to hold the y-values for the upper and lower sides
of the box, while left and right hold the x-values for the left and right sides)
(ii) Based on your answer to (i), provide a function with the following specifications:
- The function is named MoveBox and takes one InfoBox parameter named b, passed by reference,
and two float pass-by-value parameters: hmove and vmove.
- The function does not return a value.
- The function adds hmove to b's left and right fields, and adds vmove to b's
top and bottom fields. (Giving the effect of shifting the box left/right, up/down
in the plane.)
(iii) Based on your answers to (i) and (ii), write a code segment that meets the
following specifications:
Given that an array of boxes has already been declared as
InfoBox boxes[SOMESIZE];
and that values have already been set in float variables hshift and vshift,
the code segment should use your function from (ii) to shift each of the boxes
in the array by the specified hshift and vshift amounts.
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!