CS-211 Fall 2017 Test 2 Version A November 29, 2017 True/False Questions... Name: 1. (10 points) For the following, Check T if the statement is true, the F if the statement is false. (a) T F : The control variable in a for loop, for example the j in for(j=0; j <10; j++) {..., must always increase in value. The control variable may decrease, or there may not even be a control variable as in for(record=getnext(); isnext(); ) { // loop through records (b) T F : When you invoke a function in C, an activation record is created that contains, among other things, memory reserved for local variable values. (c) T F : It is OK to have an endless loop, like while(1) {... as long as the continue keyword is used somewhere in the body of the loop. It is OK if there is a break keyword, but a continue still makes this an endless loop. (d) T F : In gdb, the previous command will back up to the previous instruction executed, and reset all variables to the values they had at that previous instruction. There is no good way to back up in gdb. (e) T F : In a C if-then-else statement, there is an if keyword, and there may be an else keyword, but there is no then keyword.. (f) T F : It is typical to start gdb, type in the run command, and then, when the (gdb) prompt appears again, set breakpoints at the lines where you want gdb to stop. In gdb, set breakpoints BEFORE running. (g) T F : If the condition in a do {... while(... ); statement is false the first time the condition is checked, the body of the do/while loop is never executed. The body of a do/while loop is always executed the first time through the loop. (h) T F : If you declare int nums[10];, and then access this vector with nums[j], then C will check to make sure that j is never greater than 9 when you run your code. There in no run-time array bounds checking in C. (i) T F : An empty string in C takes no memory. An emptry string takes at least one byte of memory for the null terminator. (j) T F : A C program may use a pointer as an alternative to a variable name to read or write a value in memory. 2. (10 points) Check the best answer to fill in the blank in the following statements: (a) The malloc function is a C library function that reserves heap memory for a program to use. printf free malloc halloc strdup (b) The make command helps build complex C programs by keeping track of what needs to be updated, and allowing us to define recipes to build code consistently. build make gdb gcc mkdir Page 1 of 7
(c) When you read or write the value that a pointer is pointing at, you are de-referencing the pointer. de-referencing referencing abusing aliasing completing (d) A void pointer is the universal pointer because it can point to any type of value as long as the programmer casts the pointer to the correct type before using it. int general char pointer void (e) A structure can be defined only once, but may be instantiated many times in a single function. extended variabalized declared instantiated realized Page 2 of 7
3. (20 points) Given the following C program: #include <s t d i o. h> int main ( ) { const float g r a v i t y = 9.8; // g r a v i t y i s 9.8 meters per second2 int t ; // time in seconds struct { f loat speed ; f loat pos ; s t a t e [ 1 0 0 ] ; s t a t e [ 0 ]. pos =500.0; // I n i t i a l c o n d i t i o n s s t a t e [ 0 ]. speed =0.0; for ( t =1; s t a t e [ t 1]. pos >0; t++) { s t a t e [ t ]. speed=s t a t e [ t 1]. speed+g r a v i t y ; s t a t e [ t ]. pos=s t a t e [ 0 ]. pos+g r a v i t y t t / 2 ; // pos = a t t / 2 i f ( s t a t e [ t ]. pos <0.0) { s t a t e [ t ]. pos=s t a t e [ t ]. speed =0.0; int numpoints=t ; p r i n t f ( Time Height V e l o c i t y \n ) ; p r i n t f ( + + \n ) ; for ( t =0; t<numpoints ; t++) { p r i n t f ( %3d %5.1 f %5.1 f \n, t, s t a t e [ t ]. pos, s t a t e [ t ]. speed ) ; return 0 ; If the above program prints the following results: Time Height V e l o c i t y + + 0 500.0 0. 0 1 495.1 9.8 2 480.4 19.6 3 455.9 29.4 4 421.6 39.2 5 377.5 49.0 6 323.6 58.8 7 259.9 68.6 8 186.4 78.4 9 103.1 88.2 10 10.0 98.0 11 0. 0 0. 0 (a) What is the value of state[2].pos? (a) 480.4 (b) What is the value of state[3].speed? (b) -29.4 Page 3 of 7
(c) What is the value of numpoints at the end of the program? (c) 12 (d) If state[0].pos started at 1000000.0, what would break? Eventually, you would probably get a segmentation violation in the first for loop since you would overflow the bounds of the state array, and write over memory that is not a part of your program. (e) Can you suggest an assert statement that would help identify the problem above before it does any damage? If so, where would you insert the assert statement? I would add assert(t <100); as the first statement of the first for loop. 4. (30 points) (a) Using correct C syntax, define a structure to keep track of the time of day. Your structure should have fields to keep track of AM or PM, the hour (from 1 to 12... not military time), the minute, and the second. Your structure should be able to handle fractions of seconds. Please keep the hours, minutes, and seconds in a form in which you can do arithmetic on them. (In other words, a character string that contains 12:43:29.7 AM is not allowed.) struct tod { char ampm [ 3 ] ; int hour ; int minute ; f loat second ; ; (b) Write a function called newtime that takes no arguments, but returns a pointer to an instance of the structure defined above, set to midnight. (By convention, 12 AM denotes midnight and 12 PM denotes noon.) You may assume the struture is already defined. struct tod newtime ( ) { struct tod t=(struct tod ) malloc ( sizeof ( struct tod ) ) ; s t r c p y ( t >ampm, AM ) ; t >hour =12; t >minute =0; t >second =0.0; return t ; (c) Write a function called tod2secs which takes an instance of your structure, as defined above, as an argument, and returns the number of seconds since midnight (including fractional seconds.) float tod2secs ( struct tod t ) { f loat s e c s =0.0; i f (0==strcmp ( t.ampm, PM ) ) s e c s +=12 60 60; s e c s += t. hour 60 60; i f ( t. hour==12) { secs =12 60 60; Page 4 of 7
s e c s += t. minute 60 + t. second ; return s e c s ; 5. (15 points) Write a C function that takes a string (a pointer to the first of a null-terminated list of characters) as an argument, and returns the number of times two adjacent letters are the same in that string. For instance, in the string llamas have eyes and teeth, there are two ll s adjacent in llama, and two e s adjacent in teeth, so you would return 2. You may assume the same letter never occurs three times in a row in the string. You may use either pointer notation or array notation in your function. int countdup ( char s t r ) { char prev=0x00 ; int count =0; while (0 x00!= ( s t r ) ) { i f ( ( s t r)==prev ) { count++; prev =( s t r ) ; s t r ++; return count ; Or, using arrays... int countdup ( char s t r ) { int i ; int count =0; i f ( s t r [0]==0 x00 ) return 0 ; for ( i =1; s t r [ i ]!=0 x00 ; i++) { i f ( s t r [ i ]== s t r [ i 1]) count++; return count ; Page 5 of 7
6. (15 points) Given the following C header in deque.h: void r e s e t ( ) ; void push ( char in ) ; void que ( char in ) ; char pop ( ) ; char unque ( ) ; And the following C code in circbuf.c: #include deque. h #include <a s s e r t. h> int head =1; int t a i l =0; char buf [ 2 5 5 ] ; int i n c r ( int i ) { i ++; return ( i ==255)? 0 : i ; int decr ( int i ) { i ; return ( i <0)? 254 : i ; void r e s e t ( ) { head =1; t a i l =0; void push ( char in ) { a s s e r t ( head!= t a i l ) ; buf [ head]= in ; head=i n c r ( head ) ; void que ( char in ) { a s s e r t ( head!= t a i l ) ; buf [ t a i l ]= in ; t a i l=decr ( t a i l ) ; char pop ( ) { int nhead=decr ( head ) ; i f ( nhead==t a i l ) return 0 ; head=nhead ; return buf [ nhead ] ; char unque ( ) { int n t a i l=i n c r ( t a i l ) ; i f ( head==n t a i l ) return 0 ; t a i l=n t a i l ; return buf [ n t a i l ] ; And the following C code in palin.c: #include <s t d i o. h> #include deque. h int i s P a l i n ( char word ) ; int main ( int argc, char argv ) { int i ; for ( i =1; i<argc ; i ++) { p r i n t f ( %s i s%s a palindrome \n, argv [ i ], i s P a l i n ( argv [ i ] )? : not ) ; return 0 ; int i s P a l i n ( char word ) { r e s e t ( ) ; while ( ( word )!=0 x00 ) { push ( ( word ) ) ; word++; char f, l ; for ( f=pop ( ), l=unque ( ) ; f!=0 x00 && l!=0 x00 ; f=pop ( ), l=unque ( ) ) { i f ( f!= l ) return 0 ; return 1 ; Page 6 of 7
(a) Immediately after a the reset() function is invoked, and before push() or que() are invoked, what value will be returned by either the pop() or unque() functions? A 0 (zero) or null terminator. (b) If these are compiled with gcc -g -Wall -o palin palin.c circbuf.c and executed as./palin madam gets redder, what will get printed to standard output? madam is a palindrome gets is not a palindrome redder is a palindrome (c) Why did the programmer assert(head!=tail) in the push and que functions in circbuf.c? When head==tail then the buffer is full, and no more data can be added without causing errors. Question: 1 2 3 4 5 6 Total Points: 10 10 20 30 15 15 100 Bonus Points: 0 0 0 0 0 0 0 Page 7 of 7