CSCI 160: Fall Midterm 2: Sample Solutions
Sections F19N01-F19N04 (Dr. Wessels)

Question Mark
1. Loops and recursion
[6 marks]
 
2. Nested loops
[6 marks]
 
3. Arrays
[6 marks]
 
4. Null terminated char arrays
[6 marks]
 
5. Command line arguments
[6 marks]
 
Exam Total

[30 marks]

 

Question 1: Loops and recursion [6]


(i) Rewrite function f to use a loop instead of recursion.
(ii) Rewrite function g to use recursion instead of a loop.
For both functions, the behaviour (from the user perspective) of the rewritten function should be as close as possible to the behaviour of the original.
int f(int a, int b)
{
   if (a == b) {
      return a;
   } else if (a < b) {
      return b;
   } else {
      return f(a-1,b+2);
   }
}

void g(float x, float &y) { bool valid = false; do { printf("Enter a number: "); if (scanf("%f", &y) > 0) { if (y <= x) { valid = true; } } else { scanf("%*s"); } } while (!valid); }

SAMPLE SOLUTION

int f(int a, int b)
{
   while (a > b) {
      a--;
      b += 2;
   }
   return b;
// **note in the "if (a==b)" case, they're both the same value
//   so it doesn't actually matter which we return,
//   and in the "else" case we need to return b

void g(float x, float &y) { printf("Enter a number: "); if (scanf("%f", &y)) { if (y > x) { gr(x, y); } } else { gr(x, y); } }

Question 2: Nested loops [6]

Given the function shown below, show the output that would be produced by each of the following function calls:
(i) f(2,6,7)
(ii) f(4,0,3)
void f(int i, int j, int k)
{
   for (int r = 1; r < i; r++) {
       int c = j;
       do {
          c--;
          printf("%d", k);
          k--;
       } while (c > 0);
       printf("%d\n", r);
   }
}

SAMPLE SOLUTION

Note that the outer loop repeats i-1 times,
   each time the inner loop prints j-1 times (but always at least once),
                 showing values descending from k,
             then the value of r to end the line

(i) 7 6 5 4 3 2 1

(ii) 3 1
     2 2
     1 3

Question 3: Arrays [6]

Write the C++ findWithin function described by the comments/prototype below.
// findWithin searches the array contents from positions first to last,
//    looking for the first position (if any) containing the target value
// the function returns the position (if found)
//    or -1 (if not found within the specified set of positions)
int findWithin(float arr[], float target, int first, int last);

SAMPLE SOLUTION

// note that we cannot use a binary search since we don't know
//    if the array contents are sorted or not
int findWithin(float arr[], float target, int first, int last)
{
   for (int pos = first; pos <= last; pos++) {
       if (arr[pos] == target) {
          return pos; // found it for the first time
       }
   }
   return -1; // never found it
}

Question 4: Null terminated char arrays [6]

Write the C++ mix function described by the comments/prototype below.
// mix expects two null-terminated strings, str1 and str2, as parameters
//     it then swaps the characters in even-numbered positions (0,2,4,etc)
//        up to the length of the shorter string
//     when complete it returns the number of swaps performed
// e.g. if the two strings are "abcdefgh" and "12345"
//     the resulting strings will be "1b3d5fgh" and "a2c4e"
//     and the function will return 3
int mix(char str1[], char str2[]);

SAMPLE SOLUTION

// version 1, use for loop and length of shorter string,
//    skipping odd positions
int mix(char str1[], char str2[])
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int shorter = len1;
    if (len2 < shorter) {
       shorter = len2;
    }
    for (int pos = 0; pos < shorter; pos += 2) {
        // swap what's in the two strings at current pos
        char tmp = str1[pos];
        str1[pos] = str2[pos];
        str2[pos] = tmp;
    }
    return (shorter / 2);  // does int division so rounds down
}

// version 2, go til we see a null, check if we are on even or odd position
int mix(char str1[], char str2[])
{
   int pos = 0;
   while ((str1[pos] != '\0') && (str2[pos] != '\0')) {
      if ((pos % 2) == 0) {
        char tmp = str1[pos];
        str1[pos] = str2[pos];
        str2[pos] = tmp;
      }
   }
   return (pos / 2);
}

Question 5: Command line arguments [6]

Write a complete and correct C++ program that expects two command line arguments.

If passed an incorrect number of arguments the program simply displays the message "Expected two command line arguments" and ends.

If passed the correct number of arguments, it uses atoi to attempt to treat the first argument as an integer, and atof to treat the second argument as a float.

If both results are greater than zero it displays the message "Got numeric values X and Y", but subsituting the results for X and Y.

If either or both results are less than or equal to zero, it displays the message "Invalid parameters" and displays the two command line arguments.

Several sample runs of the program are shown below (with the initial command to run the program shown in bold italics).
 ./q5x 13 5.7
Got numeric values 13 and 5.7

 ./q5x 4 junk
Invalid parameters 4 junk

 ./q5x -3.1
Expected two command line arguments

SAMPLE SOLUTION

#include <cstdio>
#include <cstdlib>

int main(int argc, char* argv[])
{
   if (argc != 3) {
      printf("Expected two command line arguments\n";
   } else {
      int arg1 = atoi(argv[1]);
      float arg2 = atof(argv[2]);
      if ((arg1 <= 0) || (arg2 <= 0)) {
         printf("Invalid parameters %s, %s\n", argv[1], argv[2]);
      } else {
         printf("Got numeric values %d and %g\n", arg1, arg2);
      }
   }
   return 0;
}

  CSCI 160 Exam Quick Reference Sheet: Sections F19N01-F19N04
Comments:    Single line //       or Multi-line  /* ....
                                                    .... */
C++ operators
=============
Arithmetic operators:     +   -   *   /   %   ++  --
Assignment operators:  =  +=  -=  *=  /=  %=
Boolean operators:     &&  ||  !  ==  !=  <=  >=  <  >

Data Types
=======================================================
Data        Keywords             Literal Examples    Special values
integers:   short, int, long     3, -200, 0          INT_MAX, INT_MIN  (climits library)
reals:      float, double        3.14, -0.0003       FLT_MAX, FLT_MIN  (cfloat  library)
character:  char                 'x'                 \'  \"  \\  \t \n  \0
boolean:    bool                 true, false

Sample variable declarations (with/without initialization)
==========================================================
int    i;       int    i = 3;
char   c;       char c = 'Q';   char c = '\n';
bool   b;       bool b = true;
long arr[5];    long arr[5] = { 0, 0, 0, 0, 0 };   // array assignment only valid
char str[10];   char str[] = "some text";          //    at point of declaration

Sample constant declarations
============================
const double Pi = 3.1415;
const char*  ErrMsg = "Error: something terrible happened!\n";
const char[] ErrMsg = "Error: something terrible happened!\n"; // works like char*

Sample input with scanf, fgets, and getc (cstdio library)
=========================================================
scanf("%c", &x);  // read a character into char variable x
scanf("%d", &i);  // read an integer into int variable i
scanf("%ld", &n);  // read an integer into long variable n
scanf("%g", &f);  // read a real number into float variable f
scanf("%s", &a);  // read text into variable a (char[])
scanf("%*s");     // read and discard the next word of input
scanf("%[abc]", &x); // read an a, b, or c into variable x
scanf("%*[ \t\n]%c", &x); // skip tabs, spaces, and newlines and read next char into x
scanf("%4d", &i); // read a maxium of 4 digits into int variable i
fgets(arr, 100, stdin); // read the rest of the line (up to 100 chars max) into the char array
x = getc(stdin);  // read a single character into char variable x
ungetc(c, stdin); // take char c and push it into the input buffer

Sample output with printf (cstdio library)        
==========================================        
printf("%c", x);  // print the contents of  char variable c
printf("%d", i);  // print the contents of int variable i
printf("%ld", n);  // print the contents of long variable n
printf("%g", f);  // print the contents of float variable f 
  // (%f gives fixed point, %e gives exponential notation, %g can do either)
printf("%5.2g, f); // print the contents of f with width 5, 2 decimal places
printf("%s", a);  // print the contents of character array a

Some useful library functions and constants
===========================================
cctype                 cfloat                   cmath
------                 ------                   -----
bool isalpha(char)     FLT_MIN, FLT_MAX         double ceil(double)
bool isalnum(char)     DBL_MIN, DBL_MAX         double floor(double)
bool isdigit(char)                              double fabs(double)
bool islower(char)     climits                  double log(double)
bool isupper(char)     -------                  double pow(double, double) 
bool ispunct(char)     CHAR_MIN, CHAR_MAX       double cos(double)
bool isspace(char)     SHORT_MIN, SHORT_MAX     // also acos, sin, asin, tan, atan
char tolower(char)     INT_MIN, INT_MAX         double sqrt(double)
char toupper(char)     LONG_MIN, LONG_MAX

cstring                              cstdlib
-------                              -------
char[] strcat(char[],  char[])       int abs(int)
char[] strncat(char[], char[], int)  int atoi(char[])
char[] strcpy(char[],  char[])       float atof(char[])
char[] strncpy(char[], char[], int)  void srand(time(NULL)) // needs ctime lib 
int    strcmp(char[],  char[])       int rand(int)
int    strncmp(char[,] char[], int)
int    strlen(char[]

Sample control structures
=========================
if (expr) {                  // works on short, int, long,      for (x = 1; x < 9; x++) {
   .......                   //    char, or enum values             ....
} else if (expr) {           switch (expr) {                    }
   ........                     case value1:
} else {                            .....                       while (x < 9) {
   ........                         break;                          ....
}                               case value2:                        x++;
                                    .....                       }
// is X between 3 and 9?            break;
if ((3 < X) && (X < 9)) {       default:                        do {
   // yes it is                     .....                           ....
} else {                            break;                          x++;
   // no it isn't            };                                 } while (x < 9);
}
         Sample function prototypes and implementations         Sample calls
         ==============================================         ============
void swap(int &a, int &b);      float calc(int x, float f)      int main()
......                          .....                           {
void swap(int &a, int &b)       float calc(int x, float f)         int i = 1;
{                               {                                  int j = 2;
    int temp = a;                  float result = x * f;           swap(i, j);
    a = b;                         return result;                  float f = calc(i, 2.5);
    b = temp;                   }                                  int array[20];
}                                                                  initArray(array, 20);
                                                                }
                                          // command line args
void initArray(int arr[], int size)       int main(int argc, char* argv[])
{                                         {
   for (int i = 0; i < size; i++              for (int i = 0; i < argc; i++) {
       arr[i] = 0;                                printf("%s\n", argv[i]);
}                                             }
                                          }