Question | Mark |
Remembering to write your name! [1 mark] | |
1. Input/output, error checking
[11 marks] | |
2. Scopes and parameter passing
[11 marks] | |
3. Nested loops:
[11 marks] | |
4. Null-terminated character arrays:
[11 marks] | |
5. Functions and arrays:
[11 marks] | |
6. Arrays of structs:
[11 marks] | |
7. Pointers:
[11 marks] | |
8. Recursion:
[11 marks] | |
9. File I/O:
[11 marks] | |
Exam Total [100 marks] |
Question 1: Input, output, and error checking [11]
Implement the obtainData function prototyped below.
float obtainData(long min, long max, long &userVal); // First, obtainData gets the user to provide an integer value // in the range min..max (inclusive). It checks the value // is an integer and is in the correct range, gives an // appropriate error message if not, and repeats until the // user provides a suitable value // After the valid integer value has been obtained, the function // then gets the user to enter a float that is greater than // the integer value they provided in the first step. Again, // appropriate error messages are provided and the process // repeats until a valid number is obtained. // Finally, the function stores the integer value in parameter userVal, // and returns the floating point number obtained. // a typical call might look like // x = obtainData(13, 27, y); |
Sample solution float obtainData(long min, long max, long &userVal) { int scanC; long val; do { printf("Enter a number in the range %ld to %ld\n", min, max); scanC = scanf("%ld", &val); if (scanC < 1) { printf("That was not a number, please try again\n"); scanf("%*s"); } else if ((val < min) || (val > max)) { printf("%ld is not in the range %ld to %ld, please try again\n", val, min, max); } } while ((scanC < 1) || (val < min) || (val > max)); float val2; do { printf("Enter a number bigger than %ld\n", val); scanC = scanf("%g", &val2); if (scanC < 1) { printf("That was not a number, please try again\n"); scanf("%*s"); } else if (val2 <= val) { printf("%g is not bigger than %ld, please try again\n", val2, val); } } while ((scanC < 1) || (val2 <= val)); userVal = val; return val2; } |
Question 2: Scopes and parameter passing [11]
Show the precise and complete output from the following program:
#include <cstdio> const int a = 1; const int y = 5; const int x = 8; void f(int x, int &y); int main() { const int y = 3; int a = 7; printf("main1: y(%d), a(%d), x(%d)\n", y, a, x); f(y, a); printf("main2: y(%d), a(%d), x(%d)\n", y, a, x); f(x, a); printf("main3: y(%d), a(%d), x(%d)\n", y, a, x); } void f(int x, int &y) { if (x > 5) { for ( ; y < 9; y++) { printf("f1: y(%d), a(%d), x(%d)\n", y, a, x); x--; } } else { for (int y = 1; y < x; y++) { printf("f2: y(%d), a(%d), x(%d)\n", y, a, x); } } } |
Sample solution main1: y(3), a(7), x(8) f2: y(1), a(1), x(3) f2: y(2), a(1), x(3) main2: y(3), a(7), x(8) f1: y(7), a(1), x(8) f1: y(8), a(1), x(7) main3: y(3), a(9), x(8) |
Question 3: Nested loops [11]
(i) Show the output from the code segment below
for (int i = 1; i < 4; i++) { printf("row %d: ", i); for (int j = i; j < 8; j++) { printf("%4d", (10*j+i)); if (j == 7) { printf("\n"); } } } |
for (int i = 1; i < 4; i++) { printf("row %d: ", i); int j = i; do { printf("%d, ", (10*j+i)); j = j+2; } while (j < 8); printf("\n"); } |
Sample solution row 1: 11 21 31 41 51 61 71 row 2: 22 32 42 52 62 72 row 3: 33 43 53 63 73 |
Question 4: Null-terminated character arrays [11]
(i) Write the repstr function described by the prototype and comments below. You can assume the cstdio, cstring, cstdlib, and cctype libraries have all been included.
// assuming str contains a null terminated character array, and is sufficiently // large, replace the current contents of str with n copies of the string // e.g. suppose myStr currently contains "hello", // then repstr(myStr,3) would change its contents to "hellohellohello" void repstr(char str[], int n); |
Sample solution void repstr(char str[], int n) { // make a temporary copy of str, then append the copy to the original n times int sz = strlen(str); char *str2 = new char[sz + 1]; if (!str2) { return; } strcpy(str2, str1); for (int i = 0; i < n; i++) { strcat(str1, str2); } delete [] str2; } |
Question 5: Functions and arrays [11]
Write the contentSwap function described with the prototype below.
// assuming both arrays are large enough, swap the first N elements // of arr1 with the first N elements of arr2 // e.g. long data[7] = { 1, 2, 3, 4, 5, 6, 7 }; // long stuff[5] = { 10, 20, 30, 40, 50 }; // contentSwap(data, stuff, 3); // new contents of the arrays should be // data: { 10, 20, 30, 4, 5, 6, 7 }; // stuff: { 1, 2, 3, 40, 50 }; void contentSwap(long arr1[], long arr2[], int N); |
Sample solution void contentSwap(long arr1[], long arr2[], int N) { for (int i = 0; i < N; i++) { long tmp = arr1[i]; arr1[i] = arr2[i]; arr2[i] = tmp; } } |
Question 6: Arrays of structs [11]
Suppose we have a program with the following struct definition and prototypes:
// represent a time as three integers (hour 1-12, minute 0-59, second 0-59) struct TimeOfDay { int hour, minute, second; }; // fills an array of times with values supplied by the user void fill(TimeOfDay arr[], int numTimes); // prints an array of times, one per line, // formatting each time as hh:mm:ss (e.g. 11:04:59) void print(TimeOfDay arr[], int numTimes); |
(i) Write a main routine that declares an array of 100 TimeOfDays, calls fill to fill it and print to print it.
(ii) Write the print routine described with the prototype above.
Sample solution int main() { TimeOfDay array[100]; fill(array, 100); print(array, 100); } |
Question 7: Pointers [11]
(i) Rewrite the swap function below to use pointers instead of pass-by-reference to achieve the same effect.
void swap(int &x, int &y) { int tmp = x; x = y; y = tmp; } |
(ii) Rewrite the display function below to expect a pointer to a coord struct (the definition of the coord struct is provided) instead of a copy of a struct.
// x and y coordinates represented as integers struct coord { int x, y; }; void display(coord c) { printf("(%d, %d)\n", c.x, c.y); } |
(iii) Write a C++ code segment that declares arr as a pointer to an int, uses new to dynamically allocate an array of 13 floats and store the result in arr, and displays an error message if arr is null afterwards.
(iv) Write a C++ code segment that tests if arr is null, and deallocates the associated storage if it is not.
Sample solution void swap(int *x, int *y) { int tmp = *x; *x = *y; *y = tmp; } |
Question 8: Recursion [11]
Write the recursive findSmallest function described with the prototype below.
// findSmallest takes as parameters an array of floats, // a starting position in the array, and the number of elements in the array // it recursively finds the smallest value (in positions start through size-1) // and returns the position in which the value was found, // or -1 if there is no value (i.e. if start >= size) // e.g. float arr[6] = { 10, 0, 3, 9, 1, 16 }; // pos = findSmallest(arr, 2, 6); // pos should be 4 int findSmallest(float arr[], int start, int size); |
Suggested algorithm: if size <= start return -1 if size == start+1 return start otherwise call findSmallest(arr, start+1, size) to get the location of the smallest value in the rest of the array then compare what's in arr[start] to what's in the array in that position to figure out where the overall smallest value is
Sample solution int findSmallest(float arr[], int start, int size) { if (size <= start) { return -1; } else if (size == (start+1)) { return start; } int pos = findSmallest(arr, start+1, size); if ((pos >= 0) && (arr[pos] < arr[start])) { return pos; } return start; } |
Question 9: File I/O [11]
Suppose we have a data file, Names.txt, that contains the following text:
1 doos Scoobert (Scooby) Doo 2 blaked Daphne Blake 3 dinkleyv Velma Dinkley 4 rogersn Norville (Shaggy) Rogers 5 jonesf Fred Jones 6 |
#include <cstdio> const int MaxLen = 256; int main() { FILE *fpin; fpin = fopen("Names.txt", "r"); if (fpin != NULL) { while (!feof(fpin)) { char word[MaxLen], line[MaxLen]; long id; if (fscanf(fpin, "%ld", &id) > 0) { fscanf(fpin, "%s", word); fgets(line, MaxLen-1, fpin); printf("Id %ld (%s) %s", id, word, line); } else { fgets(line, MaxLen-1, fpin); printf("Non-id at start of line: %s", line); } } fclose(fpin); } } |
Sample solution Id 1 (doos) Scoobert (Scooby) Doo Id 2 (blaked) Daphne Blake Id 3 (dinkleyv) Velma Dinkley Id 4 (rogersn) Norville (Shaggy) Rogers Id 5 (jonesf) Fred Non-id at start of line: Jones Id 6 (jonesf) Jones |
CSCI 160 Exam Quick Reference Sheet: Sections F15N01-F15N04 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"; Sample enumerated type definitions ================================== enum Weekdays { Sun, Mon, Tue, Wed, Thu, Fri, Sat }; enum Commands { Quit = 'Q', Continue = 'C', Print = 'P' }; 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 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 Sample file i/o with fgets, fscanf, fprintf, getc, and ungetc (all cstdio) ========================================================================== // examples of opening / closing FILE *fpin = fopen("filename", "r"); "r", "w", or "a" if (fpin == NULL) { // failed to open } fclose(fpin); // only if file successfully opened // examples of reading from file fscanf(fpin, "%4d", &i); // from the file specified, read a maxium of 4 digits into int variable i fgets(arr, 100, fpin); // read the rest of the line (up to 100 chars max) into the char array x = getc(fpin); // read a single character into char variable x ungetc(c, stdin); // take char c and push it into the input buffer // testing for end of file if (feof(fpin)) { // end of file has been detected } // examples of writing to file fprintf(fpout, "%4d", i); 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); } void initArray(int arr[], int size) { for (int i = 0; i < size; i++ arr[i] = 0; } Pointer examples ================ int i; // an integer variable i int *iPtr; // iPtr can point at integers in memory iPtr = &i; // iPtr now points at variable i (& takes the address of i) (*iPtr) = 3; // store 3 whereever iPtr points in memory Sample function prototype with a pointer passed by reference ============================================================ void doSomething(int* &ptr); Dynamic memory allocation and deallocation ========================================== using new/delete using malloc/free ---------------- ----------------- int *i = new int; int *i = (int*)malloc(sizeof(int); // alloc new int delete i; free i; // free the int float *f = new float[10]; float *f = (float*)malloc(sizeof(float)); // alloc new arr of floats delete [] f; free f; // free the array // remember to test for NULL after any call to new or malloc Sample struct definition and use =================================== struct Info { Info i; char initials[2]; i.id = 0; int id; i.value = -34.216; float value; i.initials[0] = 'D'; }; The C++ string class (using thelibrary) ==================== std::string str; // declare a string variable str str = "blah blah blah"; // assign text to a string printf("%s", str.c_str()); // print the string contents str[3] = 'x'; // change the fourth character in the string to x