This material is provided to the professors and students using Computer Science: A Structured Approach Using C, Second Edition. All reprints in any form must cite this copyright. Copyright(c) 2001 by Brooks/Cole A division of Thomson Learning Chapter 12 Derived Types— Enumerated, Structure, and Union Review Questions 1. b. False 2. b. False 3. b. False 4. a. True 5. a. True 6. c. Float 7. d. type definition 8. d. integer 9. d. The enumerated values are automatically assigned constant values unless otherwise directed. 10. b. field 11. e. C has three different structure declarations: variable, tagged, and type-defined structures. 12. d. type-defined 13. c. stu.major 14. b. prt->name 15. d. union 16. a. true b. false c. true d. true 17. a. true b. false c. false d. true Exercises 18. struct STUDENT { int studentId; char *first; char *last; int totCr; float gpa; }; 19. typedef struct { int partNo; char *descr; int reOrder; int onHand; char unitMeas[9]; float price; } ITEM; Page 12.1 20. 21. 22. 23. 24. struct ARRAY_ELEMENT { short month; char *alphaMonth; short days; }; struct ARRAY_ELEMENT array[12] = { {1, "Jan", 31}; {2, "Feb", 28}; ... {12, "Dec", 31}; }; struct ARRAY_ELEMENT { char *month; int days; char *activity; }; struct ARRAY_ELEMENT calendar [366]; a. valid b. valid c. not valid: keyword struct invalid d. valid e. valid a. valid b. not valid: y is pointer to a character c. valid d. valid e. valid See Figure 12.1. Figure 12.1 Figure for Exercise 24 25. 12.450000 66 0 Problems 26. /* Global Declaration */ typedef struct { int hour; int min; Page 12.2 int sec; } TIME; /* =================== elapsedTime =================== Return a time structure containing the time elapsed. Pre start time structure end time structure (assumed after start) Post returns structure containing elapsed time */ TIME elapsedTime (TIME startTime, TIME endTime) { /* Local Definitions */ TIME time; /* Statements */ time.sec = endTime.sec – startTime.sec; time.min = endTime.min – startTime.min; time.hour = endTime.hour – startTime.hour; if (time.sec < 0) { time.sec += 60; time.min--; } /* if */ if (time.min < 0) { time.min += 60; time.hour--; } /* if */ if (time.hour < 0) time.hour += 24; } return time; /* elapsedTime */ 27. /* Global Declaration */ typedef struct { char *month; int day; int year; } DATE; typedef struct { int month; int days; char *name; } MONTH; /* ===================== increment ==================== This function increments date held in a DATE structure by one day. Pre oldDate is a DATE structure Page 12.3 Post returns a structure containing the new date. */ DATE increment (DATE oldDate) { /* Local Definitions */ int i; DATE newDate; MONTH table[12] = {{1, 31, "JAN"}, {2, 28, "FEB"}, {3, 31, "MAR"}, {4, 30, "APR"}, {5, 31, "MAY"}, {6, 30, "JUN"}, {7, 31, "JUL"}, {8, 31, "AUG"}, {9, 30, "SEP"}, {10,31, "OCT"}, {11,30, "NOV"}, {12,31, "DEC"}}; /* Statements */ /* check for leap year */ if (!(oldDate.year % 4) && (oldDate.year % 100) || !(oldDate.year % 400)) table[1].days++; newDate = oldDate; newDate.day++; /* find the name of month from table */ i = 0; while (strcmp (newDate.month, table[i].name)) i++; } if (newDate.day > table[i].days) { newDate.day = 1; if (!strcmp (newDate.month, table[11].name)) { newDate.year++; newDate.month = table[0].name; } /* if next year */ else newDate.month = table[i + 1].name; } /* if next month */ return newDate; /* increment */ 28. /* ============== futureDate =============== This function returns a structure showing the next date which may be in a future year. Pre structure containing in today's date integer showing number of days after today Post returns structure showing the next date */ DATE futureDate (DATE curDate, int days) Page 12.4 { /* Local Definitions */ int monthIndex; DATE fuDate; MONTH table[12] = { {1, 31, "JAN"}, {2, 28, "FEB"}, {3, 31, "MAR"}, {4, 30, "APR"}, {5, 31, "MAY"}, {6, 30, "JUN"}, {7, 31, "JUL"}, {8, 31, "AUG"}, {9, 30, "SEP"}, {10,31, "OCT"}, {11,30, "NOV"}, {12,31, "DEC"} }; /* MONTH table */ /* Statements */ fuDate = curDate; fuDate.days += days; /* find the name of month from table */ monthIndex = 0; while (strcmp(fuDate.month, table[monthIndex].name)) monthIndex++; /* check for leap year */ if ((fuDate.year % 4) && (fuDate.year % 100) || !(fuDate.year % 400)) table[1].days++; } while (fuDate.day > table[monthIndex].days) { fuDate.day -= table[monthIndex].days if (!strcmp (fuDate.month, table[11].name)) { monthIndex = 0; fuDate.year++; if (table[1].days == 29) table[1].days--; else if (!( fuDate.year % 4) && ( fuDate.year % 100) || !(fuDate.year % 400)) table[1].days++; } /* if next year */ else monthIndex++; fuDate.month = table[monthIndex].name; } /* while */ return fuDate; /* futureDate */ 29. Page 12.5 /* Global Declaration */ typedef struct { char *month; int day; int year; } DATE; typedef struct { int mon; int days; char *name; } MONTH; /* ======================= later ====================== This function returns true (1) if first date is earlier than second date and false (0) if first date is later. Pre a structure containing the first date a structure containing the second date (assumes different dates) Post returns boolean. */ int later (DATE d1, DATE d2) { /* Local Definitions */ int d1Index; int d2Index; int check; int retval; struct MONTH table[12] = { {1, 31, "JAN"}, {2, 28, "FEB"}, {3, 31, "MAR"}, {4, 30, "APR"}, {5, 31, "MAY"}, {6, 30, "JUN"}, {7, 31, "JUL"}, {8, 31, "AUG"}, {9, 30, "SEP"}, {10,31, "OCT"}, {11,30, "NOV"}, {12,31, "DEC"} }; /* MONTH table */ /* Statements */ /* check the year */ if (d1.year < d2.year) retval = 1; else if (d1.year > d2.year) retval = 0; else /* same year */ { d1Index = 0; while (strcmp (d1.month, table[d1Index].name)) Page 12.6 d1Index++; d2Index = 0; while (strcmp (d2.month, table[d2Index].name)) d2Index++; } if (d1Index < d2Index) retval = 1; else if (d1Index > d2Index) retval = 0; else /* same month */ { if (d1.day < d2.day) retval = 1; else if (d1.day > d2.day) retval = 0; else /* same date */ retval = 0; } /* else same month */ } /* else same year */ return retval; /* later */ 30. /* Global Declaration */ typedef struct { int d100; int d50; int d20; int d10; int d5; int d1; } MONEY; /* ======================= bills ====================== This function accepts an integer representing money in dollars (no fractions) and returns a structure with 6 fields: $ 100, $50, $20, $10, $5, and $1. Pre integer representing money in dollars Post returns minimum bill breakdown */ MONEY bills (int total) { /* Local Definitions */ MONEY bill; int temp = total; /* Statements */ bill.d100 = temp temp %= 100; bill.d50 = temp temp %= 50; bill.d20 = temp temp %= 20; bill.d10 = temp temp %= 10; bill.d5 = temp bill.d1 = temp / 100; / 50; / 20; / 10; / 5; % 5; Page 12.7 } return bill; /* bills */ 31. #define TOLERANCE .00001 /* Global Declaration */ typedef struct { int numerator; int denominator; } FRACTION; /* ==================== fractionCmp ================== This function compares two fraction structures. If fractions are equal, it returns zero. If first parameter < fraction in second parameter, it returns a negative number. Otherwise, it returns a positive number. Pre two fraction structures Post returns the result of comparison */ int fractionCmp (FRACTION fr1, FRACTION fr2) { /* Local Definitions */ int retval; float a; float b; /* Statements */ a = (float) fr1.numerator / fr1.denominator; b = (float) fr2.numerator / fr2.denominator; } if (fabs (a – b) < TOLERANCE) retval = 0; else if (a < b) retval = -1; else retval = 1; return retval; /* fractionCmp */ 32. /* Global Declaration */ typedef struct { int x; int y; } POINT; /* ==================== quadrant ==================== This function accepts a structure representing a point and returns an integer (1,2,3, or 4) that indicates in which quadrant the point is located. Pre a structure representing a point Post returns integer representing the quadrant (zero if point on an axis) Page 12.8 */ int quadrant (POINT p) { /* Local Definitions */ int retval; /* Statements */ if (p.x > 0 && retval = 1; else if (p.x < retval = 2; else if (p.x < retval = 3; else if (p.x > retval = 4; else retval = 0; } p.y > 0) 0 && p.y > 0) 0 && p.y < 0) 0 && p.y < 0) return retval; /* quadrant */ 33. /* Global Declaration */ typedef struct { int x; int y; } POINT; typedef struct { POINT beg; POINT end; } LINE; /* ====================== getLine ===================== This function accepts two POINTs and returns a structure representing a LINE. Pre the two structure representing the points Post returns structure representing a LINE */ LINE getLine (POINT p1, POINT p2) { /* Local Definitions */ LINE line; /* Statements line.beg.x line.beg.y line.end.x line.end.y } */ = p1.x; = p1.y; = p2.x; = p2.y; return line; /* getLine */ 34. /* Global Declaration */ typedef struct { int x; Page 12.9 int y; } POINT; typedef struct { POINT beg; POINT end; } LINE; /* ===================== checkLine ==================== This function accepts the structure of type LINE and returns an integer (1,2,3) where 1 means vertical, 2 means horizontal, and 3 means oblique. Pre a structure representing valid LINE Post a checking result */ int checkLine (LINE ln) { /* Statements */ if (ln.beg.x == ln.end.x) return 1; else if (ln.beg.y == ln.end.y) return 2; else return 3; } /* checkLine */ 35. /* Global Declarations */ typedef struct { char *suit; int value; } CARD; typedef CARD DECK[52]; /* ====================== shuffle ===================== This function shuffles a deck of cards. Pre A deck of cards that has been initialized Post The deck has been shuffled */ void shuffle (DECK deck) { /* Local Definitions */ int random; int cur; int shuffler; CARD temp; /* Statements */ srand (time (NULL)); for (cur = 0; cur < 52; cur++) { random = rand() % 52; temp = deck[random]; deck[random] = deck[cur]; deck [cur] = temp; Page 12.10 } /* for */ } return; /* shuffle */ 36. #include <stdio.h> #include <string.h> #define ARRAY_SIZE 5 #define FLUSH while(getchar() != '\n') /* Global Declarations */ typedef struct { char first[20]; char init; char last[30]; } PERSON; typedef struct { char type; union { char company[40]; PERSON person; } un; } NAME; /* Prototype Declarations */ void buildArray (NAME ary[]); void printArray (NAME ary[]); int main (void) { /* Local Definitions */ NAME ary[ARRAY_SIZE]; /* Statements */ buildArray (ary); printArray (ary); return 0; } /* main */ /* =================== buildArray =================== This function fills an array with NAMEs Pre ary is an array of NAME structures Post Array has been filled with names */ const char *errMsg = "\n\a**Invalid code - try again ===\n\n"); void buildArray (NAME ary[]) { /* Local Definitions */ char input; int index = 0; Page 12.11 /* Statements */ while (index < ARRAY_SIZE) { printf ("Enter C for company--P for person: "); scanf ("%c", &input); FLUSH; input = toupper(input); switch (input) { case 'C' : ary[index].type = input; printf ("\nEnter company name: "); fgets (ary[index].un.company, COMPANY_SIZE - 1, stdin); ary[index].un.company [strlen(ary[index].un.company)-1] = '\0'; index++; break; case 'P' : ary[index].type = input; printf ("\nEnter person’s name: "); scanf ("%s %c %s", ary[index].un.person.first, &ary[index].un.person.init, ary[index].un.person.last); FLUSH; index++; break; default : printf ("%s", errMsg); break; } /* switch Company or Person */ } /* while each NAME in ary */ return; } /* buildArray */ /* =================== printArray =================== This function prints an array of NAME structures Pre ary is an array of NAME structures Post Array has been printed */ void printArray (NAME ary[]) { /* Local Definitions */ int index; /* Statements */ for (index = 0; index < ARRAY_SIZE; index++) { switch (ary[index].type) { case 'C' : printf ("Company: %s\n", ary[index].un.company); break; case 'P' : printf ("Person : %s %c. %s\n", Page 12.12 } ary[index].un.person.first, ary[index].un.person.init, ary[index].un.person.last); break; } /* switch Company or Person */ } /* for each NAME*/ return; /* printArray */ 37. #include <stdio.h> #include <ctype.h> #include <string.h> #define #define #define #define #define ARRAY_SIZE 5 FIRST_SIZE 20 LAST_SIZE 30 COMPANY_SIZE 40 FLUSH while(getchar() != '\n') /* Global Declarations */ typedef struct { char first[FIRST_SIZE]; char init; char last[LAST_SIZE]; } PERSON; typedef struct { char type; union { char company[COMPANY_SIZE]; PERSON person; } un; } NAME; /* Prototype Declarations */ void buildArray (NAME ary[]); void sortArray (NAME ary[]); void copy (NAME *dest, NAME src); int lessThan (NAME name1, NAME name2); void printArray (NAME ary[]); int main (void) { /* Local Definitions */ NAME ary[ARRAY_SIZE]; /* Statements buildArray sortArray printArray } */ (ary); (ary); (ary); return 0; /* main */ Page 12.13 /* =================== buildArray =================== This function fills an array with NAMEs Pre ary is an array of NAME structures Post Array has been filled with names */ const char *errMsg = "\n\a**Invalid code - try again \n\n"); void buildArray (NAME ary[]) { /* Local Definitions */ char input; int index = 0; /* Statements */ while (index < ARRAY_SIZE) { printf ("Enter C for company--P for person: "); scanf ("%c", &input); FLUSH; input = toupper(input); switch (input) { case 'C' : ary[index].type = input; printf ("\nEnter company name: "); fgets (ary[index].un.company, COMPANY_SIZE - 1, stdin); ary[index].un.company [strlen(ary[index].un.company)-1] = '\0'; index++; break; case 'P' : ary[index].type = input; printf ("\nEnter person name: "); scanf ("%s %c %s", ary[index].un.person.first, &ary[index].un.person.init, ary[index].un.person.last); FLUSH; index++; break; default : printf ("%s", errMsg); break; } /* switch Company or Person */ } /* for each NAME in ary */ } return; /* buildArray */ /* =================== sortArray =================== This function sorts an array of NAME structures Pre ary is an array of NAME structures Post Array has been sorted */ Page 12.14 void sortArray (NAME ary[]) { /* Local Definitions */ int walker1; int walker2; NAME temp; /* Statements */ for (walker1 = 1; walker1 < ARRAY_SIZE; walker1++) { walker2 = walker1; copy (&temp, ary[walker2]); while (walker2 > 0 && lessThan (temp, ary[walker2 - 1])) { copy (&ary[walker2], ary[walker2 - 1]); walker2--; } /* while */ copy (&ary[walker2], temp); } /* for */ } printArray (ary); return; /* sortArray */ /* =================== copy ====================== This function copies one NAME structure to another Pre src and dest are NAME structures Post src copied to dest */ void copy (NAME *dest, NAME src) { /* Statements */ dest->type = src.type; switch (src.type) { case 'C' : strcpy (dest->un.company, src.un.company); break; case 'P' : strcpy (dest->un.person.first, src.un.person.first); dest->un.person.init = src.un.person.init; strcpy (dest->un.person.last, src.un.person.last); break; } /* switch Company or Person */ return; } /* copy */ /* =================== lessThan ===================== This function compares 2 NAME structures Pre name1 and name2 are NAME structures Post NAME structures compared Returns 1 if name1 < name2, 0 otherwise */ int lessThan (NAME name1, NAME name2) Page 12.15 { /* Local Definitions */ int length; int retval; char ary1[60]; char ary2[60]; char *walker1; char *walker2; /* Statements */ switch (name1.type) { case 'C' : walker1 = name1.un.company; walker2 = ary1; while (*walker1 != '\0') { if (!isspace (*walker1)) { *walker2 = toupper(*walker1); walker2++; } /* if */ walker1++; } /* while */ *walker2 = '\0'; break; case 'P' : strcpy (ary1, name1.un.person.last); strcat (ary1, name1.un.person.first); length = strlen (ary1); ary1[length] = name1.un.person.init; ary1[length + 1] = '\0'; walker1 = ary1; while (*walker1 != '\0') { *walker1 = toupper(*walker1); walker1++; } /* while */ break; } /* switch Company or Person */ switch (name2.type) { case 'C' : walker1 = name2.un.company; walker2 = ary2; while (*walker1 != '\0') { if (!isspace (*walker1)) { *walker2 = toupper(*walker1); walker2++; } /* if */ walker1++; } /* while */ *walker2 = '\0'; break; case 'P' : strcpy (ary2, name2.un.person.last); strcat (ary2, name2.un.person.first); length = strlen (ary2); Page 12.16 ary2[length] = name2.un.person.init; ary2[length + 1] = '\0'; walker1 = ary2; while (*walker1 != '\0') { *walker1 = toupper(*walker1); walker1++; } /* while */ break; } /* switch Company or Person */ if (strcmp (ary1, ary2) retval = 1; else retval = 0; } < 0) return retval; /* lessThan */ /* =================== printArray =================== This function prints an array of NAME structures Pre ary is an array of NAME structures Post Array has been printed */ void printArray (NAME ary[]) { /* Local Definitions */ int index; /* Statements */ for (index = 0; index < ARRAY_SIZE; index++) { switch (ary[index].type) { case 'C' : printf ("Company: %s\n", ary[index].un.company); break; case 'P' : printf ("Person : %s %c. %s\n", ary[index].un.person.first, ary[index].un.person.init, ary[index].un.person.last); break; } /* switch Company or Person */ } /* for each NAME*/ return; } /* printArray */ Page 12.17