Practice Exam
Transcription
Practice Exam
This practice midterm for Winter 2015 CS107 was the actual midterm for Julie Zelenski’s Autumn 2014. CS107 J Zelenski Handout #4 Halloween 2014 Midterm Examination Your exam should have 6 pages and there are 3 questions worth a total of 70 points. The time allotted is 75 minutes. Write your answers directly on the exam, including any work that you wish to be considered for partial credit. The exam is closed-book and closed-device; you may refer only to your one page of prepared notes. You may use functions from the standard C libraries unless otherwise restricted in the problem instructions. The last page of the exam is a list of common function prototypes. Your code does not need #include statements, nor must you declare prototypes. Comments are not required, but may earn partial credit if your intentions are correct but your code is wrong. We thank you in advance for writing more neatly than you have in your entire life. Name (printed) __________________________________________________________ SUNet username (i.e. myth login) ________________________ NVidia seat location: Row letter (label on armrest at end of your row) _______________ Seat number (label on bottom front edge of seat) _______________ SCPD students: Check here ☐ if you want your graded exam returned via SCPD distribution. By signing my name, I confirm I will fully abide by the letter and spirit of the Honor Code when completing this exam. (signed) ________________________________________________________________ Score Grader 1. C-strings and generic client (25) ______ ______ 2. C generics implementation (25) ______ ______ 3. Bits, bytes, and numbers (20) ______ ______ Total (70) ______ Page 2 of 6 Problem 1: C-strings and client of generic interfaces (25 points) We define a word's signature to be the string containing the letters of the word in sorted order. For example, the signature of "apple" is "aelpp" and the signature of "bell" is "bell". Write the make_map function below to take a CVector of words and fill a CMap with entries mapping each word (key) to its signature (value). The CVector was created using cvec_create(sizeof(char*), capacity, cleanup). You can assume the cleanup function is already correctly implemented. To form a word's signature, sort its letters into alphabetical order. You must use qsort and this will require that you write an appropriate callback function. You may assume the words consist only of lowercase letters. CMap *make_map(const CVector *cv) { CMap *cm = cmap_create(sizeof(char*), cvec_count(cv), cleanup); Page 3 of 6 Problem 2: Implementing generic interfaces (25 points) Complete the make_list function started below that takes a generic array of elements and creates a linked list of those same elements. The function's three arguments are the base address of the array, the number of elements in the array, and the size of each element in bytes. The function returns a pointer to a linked list of cells, one cell for each element in the array. The order of the elements in the list is the same as in the array. Each list cell consists of an element of elemsz bytes and a pointer to the next cell (null if this is the last cell). The element and the pointer are laid out in contiguous memory as shown below: void *make_list(const void *arr, int nelems, int elemsz) { void *list = NULL; for (int i = nelems-1; i >= 0; i--) { // prepend ith elem to front of list Page 4 of 6 Problem 3: Bits, bytes, and numbers (20 points) a) The discrete binary logarithm, defined for positive N, is the value of log2N rounded down to an integer. For example, the discrete binary logarithm of 7 is 2. What must the bit patterns of two integers have in common in order to have the same discrete binary logarithm? b) Write the integer function dlog to compute the discrete binary logarithm. Use a straightforward implementation which loops through all the bits. int dlog(unsigned int n) { assert(n > 0); // n is required to be positive Page 5 of 6 c) Write the float function dlogf to compute the discrete binary logarithm of a positive float value. It should accept normalized and denormalized inputs; you may ignore exceptional inputs. Your implementation must work by manipulating the underlying float bits, using only integer arithmetic and bitwise operations—no floating point operations or <math.h> functions. You may call the integer dlog function from part (b) and can assume it works correctly. Hint: it may help to separate into cases for normalized and denormalized inputs. int dlogf(float f) { assert(f > 0); unsigned int bits = *(unsigned int *)&f; // access raw bits d) Assume that the integer dlog and float dlogf functions work correctly for all valid inputs. For many float and integer values, the result from dlog((unsigned int)val) will equal dlogf((float)val), but this equality does not hold for all values. Assign n below to a constant integer expression greater than 1 such that the result from dlogf((float)n) disagrees with the correct result from dlog(n). unsigned int n = ________________________________________________ ; Assign f below to a constant float expression greater than 1 such that the result from dlog((unsigned int)f) disagrees with the correct result from dlogf(f). float f = ________________________________________________ ; Page 6 of 6 Library functions Reminder of the prototypes for potentially useful functions. You won't use every function listed. You may also use standard C library functions not on this list. size_t strlen(const char *str); char *strcpy(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t n); char *strcat(char *dst, const char *src); char *strncat(char *dst, const char *src, size_t n); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); char *strdup(const char *s); void *malloc(size_t sz); void *realloc(void *ptr, size_t sz); void free(void *ptr); void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); void *memcpy(void *dst, const void *src, size_t n); void *memmove(void *dst, const void *src, size_t n); typedef void (*CleanupFn)(void *addr); CVector int void void void *cvec_create(int elemsz, int capacity_hint, CleanupFn fn); cvec_count(const CVector *cv); *cvec_nth(const CVector *cv, int index); *cvec_first(const CVector *cv); *cvec_next(const CVector *cv, const void *prev); CMap *cmap_create(int valuesz, int capacity_hint, CleanupFn fn); void cmap_put(CMap *cm, const char *key, const void *val);