SOFTWARE – Ph.D. Qualifying Exam Spring 2013 (i) (5 pts.) Consider the C program shown below. For each of the six pointer assignment statements (PASs) annotated with comments ("stmt 1", "stmt 2", ..., "stmt 6"), clearly indicate which are legal PASs, and which are not legal PASs. #include <stdio.h> int main(void) { char *p1 = NULL, *p5 = NULL; int *p2 = NULL, *p3 = NULL, *p4 = NULL, *p6 = NULL; int a[5] = {1, 2, 3, 4, 5}; char c = '5'; p1 p2 p3 p4 p5 p6 = = = = = = &('7'); &(a[3]); &10; &(a[3 - 2]); &c; &(a[2] + 1); /* /* /* /* /* /* stmt stmt stmt stmt stmt stmt 1 2 3 4 5 6 */ */ */ */ */ */ return 0; } Indicate your solution on this page by circling Yes or No next to each of the following six questions: stmt 1: Legal? (Yes or No) stmt 2: Legal? (Yes or No) stmt 3: Legal? (Yes or No) stmt 4: Legal? (Yes or No) stmt 5: Legal? (Yes or No) stmt 6: Legal? (Yes or No) Write your solution to Question (i) on this page, as described above. Please clearly indicate your solution and show all work on this page. (ii) (5 pts.) Consider the following C program, which includes two function definitions, including the main function. #include <stdio.h> void sfunction(char *s, int x, int y) { char *p = NULL; p = &(s[y]); printf("A: %s\n", p); printf("B: %c\n", p[x]); p--; p--; printf("C: %c\n", *p); } int main(void) { char *s1 = "Maryland"; char *s2 = "Terrapins"; sfunction(s1, 2, 3); sfunction(s2, -1, 5); return 0; } Show the complete output as it appears on standard output. Write your solution to Question (ii) on this page. Please clearly indicate your solution and show all work on this page. (iii) (5 pts.) Consider the following C program. #include <stdio.h> #include <ctype.h> void display_result(int result) { static int index = 1; printf("result #%d: %d\n", index, result); index++; } int main(void) { char *s = "three/two/one", *p = s; int x = 100, iterations = 0, i = 0; iterations = 0; for (i = 0; i <= 10; i++) { iterations++; } display_result(iterations); iterations = 0; while (x > 0) { x = x / 7; iterations++; } display_result(iterations); iterations = 0; for (i = 10; i > 3; i--) { i -= 2; iterations++; } display_result(iterations); iterations = 0; while (isalpha(*p)) { p++; iterations++; } display_result(iterations); iterations = 0; for (i = 10; (i % 5) != 0; i++) { iterations++; } display_result(iterations); return 0; } Show the complete output as it appears on standard output. Write your solution to Question (iii) on this page. Please clearly indicate your solution and show all work on this page. (iv) (5 pts.) Consider the following structure definition for constructing linked lists of bank records, where each record holds the information associated with a single bank account. struct bank_record { char *first_name; char *last_name; int id; /* The dollar balance of the account in cents */ int balance; /* Pointer to the next list element */ struct bank_record *next; }; Consider also the following function prototype and associated header comment. /********************************************************************* Given a list of bank records, pointed to by the "head" argument, determine if there is a record in the list whose id matches the "id" argument. If there are multiple records whose ids match the "id" argument, then display a meaningful error message to standard error and return a null pointer. If there is exactly one record whose id matches the "id" argument, then remove that matching record from the list and return a pointer to the matching record. If there is no record whose id matches the "id" argument, then return a null pointer (without displaying any message). Assume that the first element in the list (the element pointed to by the "head" argument) is a "dummy" record whose purpose is only to mark the beginning of the list, and assume that the "id" argument does not match the id of this dummy record. *********************************************************************/ struct bank_record *delete_record(struct bank_record *head, int id); Note that no error checking is required in this function beyond what is stated in the header comment. For example, it can be assumed that the given "head" pointer is non-NULL. Develop a complete C code implementation of the function delete_record. Write your solution to Question (iv) on this page. Please clearly indicate your solution and show all work on this page. C Reference Card (ANSI) Constants Flow of Control suffix: long, unsigned, float 65536L, -1U, 3.0F Program Structure/Functions exponential form 4.2e1 prefix: octal, hexadecimal 0, 0x or 0X type fnc(type 1 , . . . ); function prototype Example. 031 is 25, 0x31 is 49 decimal type name; variable declaration character constant (char, octal, hex) 'a', '\ooo', '\xhh' int main(void) { main routine \n, \r, \t, \b declarations local variable declarations newline, cr, tab, backspace special characters \\, \?, \', \" statements string constant (ends with '\0') "abc. . . de" } function definition type fnc(arg 1 , . . . ) { declarations local variable declarations Pointers, Arrays & Structures statements declare pointer to type type *name; return value; declare function returning pointer to type type *f(); } declare pointer to function returning type type (*pf)(); /* */ comments generic pointer type void * int main(int argc, char *argv[]) main with args null pointer constant NULL exit(arg); terminate execution object pointed to by pointer *pointer address of object name &name C Preprocessor array name[dim] include library file #include <filename> multi-dim array name[dim 1 ][dim 2 ]. . . include user file #include "filename" Structures replacement text #define name text struct tag { structure template replacement macro #define name(var ) text declarations declaration of members Example. #define max(A,B) ((A)>(B) ? (A) : (B)) }; undefine #undef name create structure struct tag name quoted string in replace # member of structure from template name.member Example. #define msg(A) printf("%s = %d", #A, (A)) member of pointed-to structure pointer -> member concatenate args and rescan ## Example. (*p).x and p->x are the same conditional execution #if, #else, #elif, #endif single object, multiple possible types union is name defined, not defined? #ifdef, #ifndef bit field with b bits unsigned member : b; name defined? defined(name) line continuation char \ Operators (grouped by precedence) Data Types/Declarations character (1 byte) char integer int real number (single, double precision) float, double short (16 bit integer) short long (32 bit integer) long double long (64 bit integer) long long positive or negative signed non-negative modulo 2m unsigned pointer to int, float,. . . int*, float*,. . . enumeration constant enum tag {name 1 =value 1 ,. . . }; constant (read-only) value type const name; declare external variable extern internal to source file static local persistent between calls static no value void structure struct tag {. . . }; create new name for data type typedef type name; size of an object (type is size_t) sizeof object size of a data type (type is size_t) sizeof(type) Initialization initialize variable initialize array initialize char string type name=value; type name[]={value 1 ,. . . }; char name[]="string"; c 2007 Joseph H. Silverman Permissions on back. v2.2 statement terminator ; block delimiters { } exit from switch, while, do, for break; next iteration of while, do, for continue; go to goto label; label label: statement return value from function return expr Flow Constructions if statement if (expr 1 ) statement 1 else if (expr 2 ) statement 2 else statement 3 while statement while (expr ) statement for statement for (expr 1 ; expr 2 ; expr 3 ) statement do statement do statement while(expr ); switch statement switch (expr ) { case const 1 : statement 1 break; case const 2 : statement 2 break; default: statement } ANSI Standard Libraries <assert.h> <locale.h> <stddef.h> <ctype.h> <math.h> <stdio.h> <errno.h> <setjmp.h> <stdlib.h> <float.h> <signal.h> <string.h> Character Class Tests <ctype.h> struct member operator struct member through pointer increment, decrement plus, minus, logical not, bitwise not indirection via pointer, address of object cast expression to type size of an object name.member pointer ->member ++, -+, -, !, ~ *pointer , &name (type) expr sizeof multiply, divide, modulus (remainder) *, /, % add, subtract +, - alphanumeric? alphabetic? control character? decimal digit? printing character (not incl space)? lower case letter? printing character (incl space)? printing char except space, letter, digit? space, formfeed, newline, cr, tab, vtab? upper case letter? hexadecimal digit? convert to lower case convert to upper case left, right shift [bit ops] <<, >> String Operations <string.h> relational comparisons equality comparisons >, >=, <, <= ==, != and [bit op] & exclusive or [bit op] ^ or (inclusive) [bit op] | logical and && logical or || conditional expression expr 1 ? expr 2 : expr 3 assignment operators +=, -=, *=, . . . expression evaluation separator , Unary operators, conditional expression and assignment operators group right to left; all others group left to right. <limits.h> <stdarg.h> <time.h> isalnum(c) isalpha(c) iscntrl(c) isdigit(c) isgraph(c) islower(c) isprint(c) ispunct(c) isspace(c) isupper(c) isxdigit(c) tolower(c) toupper(c) s is a string; cs, ct are constant strings length of s copy ct to s concatenate ct after s compare cs to ct only first n chars pointer to first c in cs pointer to last c in cs copy n chars from ct to s copy n chars from ct to s (may overlap) compare n chars of cs with ct pointer to first c in first n chars of cs put c into first n chars of s strlen(s) strcpy(s,ct) strcat(s,ct) strcmp(cs,ct) strncmp(cs,ct,n) strchr(cs,c) strrchr(cs,c) memcpy(s,ct,n) memmove(s,ct,n) memcmp(cs,ct,n) memchr(cs,c,n) memset(s,c,n) C Reference Card (ANSI) Input/Output <stdio.h> Standard I/O standard input stream stdin standard output stream stdout standard error stream stderr end of file (type is int) EOF get a character getchar() print a character putchar(chr ) print formatted data printf("format",arg 1 ,. . . ) print to string s sprintf(s,"format",arg 1 ,. . . ) read formatted data scanf("format",&name 1 ,. . . ) read from string s sscanf(s,"format",&name 1 ,. . . ) print string s puts(s) File I/O declare file pointer FILE *fp; pointer to named file fopen("name","mode") modes: r (read), w (write), a (append), b (binary) get a character getc(fp) write a character putc(chr ,fp) write to file fprintf(fp,"format",arg 1 ,. . . ) read from file fscanf(fp,"format",arg 1 ,. . . ) read and store n elts to *ptr fread(*ptr,eltsize,n,fp) write n elts from *ptr to file fwrite(*ptr,eltsize,n,fp) close file fclose(fp) non-zero if error ferror(fp) non-zero if already reached EOF feof(fp) read line to string s (< max chars) fgets(s,max,fp) write string s fputs(s,fp) Codes for Formatted I/O: "%-+ 0w.pmc" - left justify + print with sign space print space if no sign 0 pad with leading zeros w min field width p precision m conversion character: h short, l long, L long double c conversion character: d,i integer u unsigned c single char s char string f double (printf) e,E exponential f float (scanf) lf double (scanf) o octal x,X hexadecimal p pointer n number of chars written g,G same as f or e,E depending on exponent Variable Argument Lists <stdarg.h> declaration of pointer to arguments va_list ap; initialization of argument pointer va_start(ap,lastarg); lastarg is last named parameter of the function access next unnamed arg, update pointer va_arg(ap,type) call before exiting function va_end(ap); Standard Utility Functions <stdlib.h> Mathematical Functions <math.h> absolute value of int n abs(n) absolute value of long n labs(n) quotient and remainder of ints n,d div(n,d) returns structure with div_t.quot and div_t.rem quotient and remainder of longs n,d ldiv(n,d) returns structure with ldiv_t.quot and ldiv_t.rem pseudo-random integer [0,RAND_MAX] rand() set random seed to n srand(n) terminate program execution exit(status) pass string s to system for execution system(s) Conversions convert string s to double atof(s) convert string s to integer atoi(s) convert string s to long atol(s) convert prefix of s to double strtod(s,&endp) convert prefix of s (base b) to long strtol(s,&endp,b) same, but unsigned long strtoul(s,&endp,b) Storage Allocation allocate storage malloc(size), calloc(nobj,size) change size of storage newptr = realloc(ptr,size); deallocate storage free(ptr); Array Functions search array for key bsearch(key,array,n,size,cmpf) sort array ascending order qsort(array,n,size,cmpf) Arguments and returned values are double Time and Date Functions <time.h> processor time used by program clock() Example. clock()/CLOCKS_PER_SEC is time in seconds current calendar time time() time2 -time1 in seconds (double) difftime(time2 ,time1 ) arithmetic types representing times clock_t,time_t structure type for calendar time comps struct tm tm_sec seconds after minute tm_min minutes after hour tm_hour hours since midnight tm_mday day of month tm_mon months since January tm_year years since 1900 tm_wday days since Sunday tm_yday days since January 1 tm_isdst Daylight Savings Time flag convert local time to calendar time mktime(tp) convert time in tp to string asctime(tp) convert calendar time in tp to local time ctime(tp) convert calendar time to GMT gmtime(tp) convert calendar time to local time localtime(tp) format date and time info strftime(s,smax,"format",tp) tp is a pointer to a structure of type tm trig functions inverse trig functions arctan(y/x) hyperbolic trig functions exponentials & logs exponentials & logs (2 power) division & remainder powers rounding sin(x), cos(x), tan(x) asin(x), acos(x), atan(x) atan2(y,x) sinh(x), cosh(x), tanh(x) exp(x), log(x), log10(x) ldexp(x,n), frexp(x,&e) modf(x,ip), fmod(x,y) pow(x,y), sqrt(x) ceil(x), floor(x), fabs(x) Integer Type Limits <limits.h> The numbers given in parentheses are typical values for the constants on a 32-bit Unix system, followed by minimum required values (if significantly different). CHAR_BIT bits in char (8) CHAR_MAX max value of char (SCHAR_MAX or UCHAR_MAX) CHAR_MIN min value of char (SCHAR MIN or 0) SCHAR_MAX max signed char (+127) SCHAR_MIN min signed char (−128) SHRT_MAX max value of short (+32,767) SHRT_MIN min value of short (−32,768) INT_MAX max value of int (+2,147,483,647) (+32,767) INT_MIN min value of int (−2,147,483,648) (−32,767) LONG_MAX max value of long (+2,147,483,647) LONG_MIN min value of long (−2,147,483,648) UCHAR_MAX max unsigned char (255) USHRT_MAX max unsigned short (65,535) UINT_MAX max unsigned int (4,294,967,295) (65,535) ULONG_MAX max unsigned long (4,294,967,295) Float Type Limits <float.h> The numbers given in parentheses are typical values for the constants on a 32-bit Unix system. FLT_RADIX radix of exponent rep (2) FLT_ROUNDS floating point rounding mode FLT_DIG decimal digits of precision (6) FLT_EPSILON smallest x so 1.0f + x = 1.0f (1.1E − 7) FLT_MANT_DIG number of digits in mantissa FLT_MAX maximum float number (3.4E38) FLT_MAX_EXP maximum exponent FLT_MIN minimum float number (1.2E − 38) FLT_MIN_EXP minimum exponent DBL_DIG decimal digits of precision (15) DBL_EPSILON smallest x so 1.0 + x = 1.0 (2.2E − 16) DBL_MANT_DIG number of digits in mantissa DBL_MAX max double number (1.8E308) DBL_MAX_EXP maximum exponent DBL_MIN min double number (2.2E − 308) DBL_MIN_EXP minimum exponent c 2007 Joseph H. Silverman January 2007 v2.2. Copyright Permission is granted to make and distribute copies of this card provided the copyright notice and this permission notice are preserved on all copies. Send comments and corrections to J.H. Silverman, Math. Dept., Brown Univ., Providence, RI 02912 USA. jhs@math.brown.edu Software Qualifying Exam Solutions Spring 2013 Dept. of ECE, University of Maryland, College Park 01/20/2013 Problem 1: stmt 1, stmt 3, and stmt 6 are NOT legal. Problem 2: A: B: C: A: B: C: yland a a pins a r Problem 3: result result result result result #1: #2: #3: #4: #5: 11 3 3 5 0 Problem 4: struct bank_record *delete_record(struct bank_record *head, int id) { struct bank_record *p = NULL; struct bank_record *last_match; int matches = 0; for (p = head; p != NULL; p = p->next) { if (p->id == id) { matches++; last_match = p; } } } if (matches == 0) { return NULL; } else if (matches > 1) { fprintf(stderr, "Error: multiple accounts have"); fprintf(stderr, "the same ID\n"); return NULL; } else { for (p = head; p->next != last_match; p = p->next); p->next = last_match->next; last_match->next = NULL; return last_match; }