1 / 98

Chapter 16

Chapter 16. Structures. Structures. A structure is a collection of one or more variables , possibly of different types , grouped together under a single name for convenient handling Structures permit a group of related variables to be treated as a unit instead of as separate entities

susan
Télécharger la présentation

Chapter 16

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 16 Structures

  2. Structures • A structure is a collection of one or morevariables, possibly of different types, grouped together under a single name for convenient handling • Structures permit a group of related variables to be treated as a unit instead of as separate entities • Variables in a structure are called fields of the structure

  3. An Example • The information for an employee: • Name • Address • Phone number • Age • Sex • Identification number • Salary

  4. An Example • struct employee { • char name[40]; • char address[100]; • char phone_number[10]; • int age; • int sex; • char id_number[10]; • int salary; • };

  5. Operations on Structures • The only legal operations on a structure: • Copying it or assigning to it as a unit • Accessing its fields with ‘.’ and field names • Taking its address with ‘&’

  6. (4,3) (0,0) An Example struct point { int x; int y; } x, y, z; struct point pt; struct point maxpt = {320, 200}; printf(“%d, %d”, pt.x, pt.y);

  7. An Example struct rec { struct point pt1; struct point pt2; }; struct rec screen; printf(“%d”, screen.pt1.x); pt2 pt1

  8. Returning Structures struct point makepoint(int x, int y) { struct point temp; temp.x = x; temp.y = y; return temp; }

  9. Returning Structures struct rect screen; struct point middle; struct point makepoint(int x, int y); screen.pt1 = makepoint(0, 0); screen.pt2 = makepoint(320, 200); middle = makepoint((screen.pt1.x + screen.pt2.x)/2, (screen.pt1.y + screen.pt2.y)/2);

  10. Structures Parameters struct point addpoint(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return p1; } int ptinrect(struct point p, struct rect r) { return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y; }

  11. Structures and Functions #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) < (b) ? (b) : (a)) struct rect canonrect(struct rect r) { struct rect temp; temp.pt1.x = min(r.pt1.x, r.pt2.x); temp.pt1.y = min(r.pt1.y, r.pt2.y); temp.pt2.x = max(r.pt1.x, r.pt2.x); temp.pt2.y = max(r.pt1.y, r.pt2.y); return temp; }

  12. Pointers to Structures struct point origin, *pp; pp = &origin; printf(“%d, %d”, (*pp).x, (*pp).y); printf(“%d, %d”, pp->x, pp->y); struct rect r, *rp = &r; r.pt1.x rp->pt1.x (r.pt1).x (rp->pt1).x

  13. Counting Occurrences of Keywords “auto” “break” “case” “char” … “volatile” “while” 0 0 0 0 … 0 0 {“auto”, 0} {“break”, 0} {“case”, 0} {“char”, 0} … {“volatile”, 0} {“while”, 0} keyword keycount keytab

  14. Arrays of Structures char *keyword[NKEYS]; int keycount[NKEYS]; struct key { char *word; int count; } keytab[NKEYS];

  15. Arrays of Structures • struct key { • char *word; • int count; • } keytab[ ] = { • {“auto”, 0}, {“break”, 0}, • {“case”, 0}, {“char”, 0}, • … • {“volatile”, 0}, {“while”, 0} • };

  16. Arrays of Structures main( ) { int n; char word[MAXWORD]; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) if ((n= binsearch(word, keytab, NKEYS)) >= 0) keytab[n].count++; for (n = 0; n < NKEYS; n++) if (keytab[n].count > 0) printf("%4d %s\n", keytab[n].count, keytab[n].word); return 0; }

  17. Arrays of Structures int binsearch(char *word, struct key tab[ ], int n) { int cond, low = 0, high = n - 1, mid; while (low <= high) { mid = (low + high) / 2; if ((cond = strcmp(word, tab[mid].word)) < 0) high = mid -1; else if (cond > 0) low = mid + 1; else return mid; } return -1; }

  18. Arrays of Structures int getword(char *word, int lim) { int c; char *w = word; while (isspace(c = getch( ))) ; if (c != EOF) *w++ = c; if (!isalpha( c )) { *w = '\0'; return c; } for (; --lim > 0; w++) if (!isalnum(*w = getch( ))) { ungetch(*w); break; } *w = '\0'; return word[0]; }

  19. Pointers to Structures main( ) { char word[MAXWORD]; struct key *p; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) if ((p= binsearch(word, keytab, NKEYS)) != NULL) p->count++; for (p = keytab; p < keytab + NKEYS; p++) if (p->count > 0) printf("%4d %s\n", p->count, p->word); return 0; }

  20. Pointers to Structures struct key *binsearch(char *word, struct key *tab, int n) { int cond; struct key *low = &tab[0], *high = &tab[n], *mid; while (low < high) { mid = low + (high - low) / 2; if ((cond = strcmp(word, mid->word)) < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else return mid; } return NULL; }

  21. Counting Occurrences of All Words now is the time for all good men to come to the aid of their party

  22. Binary Trees now the is for men of time party their to all good aid come a pointer to the text of the word a count of the number of occurrences a pointer to the left child node a pointer to the right child node

  23. Self-referential Structures struct tnode { char *word; int count; struct tnode *left; struct tnode *right; }

  24. Self-referential Structures main( ) { char word[MAXWORD]; struct tnode *root = NULL; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) root = addtree(root, word); treeprint(root); return 0; }

  25. Self-referential Structures struct tnode *addtree(struct tnode *p, char *w) { int cond; if (p == NULL) { p = talloc( ); p->word = strdup(w); p->count = 1; p->left = p->right = NULL; } else if ((cond = strcmp(w, p->word)) == 0) p->count++; else if (cond < 0) p->left = addtree(p->left, w); else p->right = addtree(p->right, w); return p; }

  26. Self-referential Structures void treeprint(struct tnode *p) { if (p != NULL) { treeprint(p->left); printf("%4d %s\n", p->count, p->word); treeprint(p->right); } }

  27. Self-referential Structures struct tnode *talloc(void) { return (struct tnode *) malloc(sizeof(struct tnode)); } char *strdup(char *s) { char *p; p = (char *) malloc(strlen(s) + 1); if (p != NULL) strcpy(p, s); return p; }

  28. Recursion • C functions may be used recursively; that is, a function may call itself either directly or indirectly • When a function calls itself recursively, each invocation gets a fresh set of all the automatic variables

  29. An Example - Iteration #include <stdio.h> int factorial(int n) { int product, i; product = 1; for (i = 1; i <= n; i++) product *= i; return product; }

  30. An Example - Recursion #include <stdio.h> int factorial(int n) { if (n = 0) { return 1; } else { return n * factorial(n – 1); } }

  31. factorial(1) factorial(2) 2 1 1 n=0 factorial(0) n=1 n=1 n=2 n=2 n=2 An Example - Recursion

  32. An Example - Iteration void itoa( int n, char s[ ] ) { int i, sign; if ((sign = n) < 0) n = -n; i = 0; do s[i++] = n % 10 + ‘0’; } while ((n /= 10) > 0); if (sign < 0) s[i++] = ‘-’; s[i] = ‘\0’; reverse(s); }

  33. An Example - Recursion #include <stdio.h> void printd( int n) { if (n < 0) { putchar(‘-’); n = -n; } if (n / 10) printd(n / 10); putchar(n % 10 + ‘0’); }

  34. printd(12) printd(123) 3 2 1 n=1 printd(1) n=12 n=12 n=123 n=123 n=123 An Example - Recursion

  35. An Example - Iteration int binsearch(char *word, struct key tab[ ], int n) { int cond, low = 0, high = n - 1, mid; while (low <= high) { mid = (low + high) / 2; if ((cond = strcmp(word, tab[mid].word)) < 0) high = mid -1; else if (cond > 0) low = mid + 1; else return mid; } return -1; }

  36. An Example - Recursion int binsearch(char *word, struct key tab[ ], int low, int high) { int cond, mid; if (low <= high) { return -1; } else { mid = (low + high) / 2; if ((cond = strcmp(word, tab[mid].word)) < 0) return binsearch(word, tab, low, mid - 1); else if (cond > 0) return binsearch(word, tab, mid + 1, high); else return mid; } }

  37. Recursion • Recursion provides no saving in storage, since the data for every invocation must be maintained • Recursion provides no saving in execution time, since time for function invocations is higher than loops • Recursive functions are more compact, much easier to write and understand

  38. An Example - Queues • A queue is a waiting line. Customers go to the back of the waiting line and wait for their turn • Some common operations on queues: • Create a new queue • Eliminate an existing queue • Add a customer to the end of the the queue • Remove a customer from the front of the queue • Determine how many customers are in the queue

  39. First Implementation • A queue is implemented as an array and the front of the queue is always the first element of the array • The length of the queue is statically determined • Removing a customer is very inefficient

  40. An Example typedef struct queue { void *array[MAXSIZE]; int len; } *queueT; array: len: 0 array: a len: 1 array: a b len: 2 array: a b c len: 3 array: b c len: 2

  41. An Example queueT newQueue(void) { queueT q; q = (queueT) malloc(sizeof(struct queue)); q->len = 0; return q; } void freeQueue(queueT q) int queueLength(queueT q) { { free((char *) q); return q->len; } }

  42. An Example void enqueue(queueT q, void *obj) { if (q->len == MAXSIZE) { error(“enqueue called on a full queue”); } q->array[q->len++] = obj; }

  43. An Example void *dequeue(queueT q) { void *result; int i; if (q->len == 0) error(“dequeue called on an empty queue”); result = q->array[0]; for (i = 1; i < q->len; i++) q->array[i - 1] = q->array[i] ; q->len--; return result; }

  44. Second Implementation • A queue is implemented as a ring buffer and the front of the queue will change dynamically • The length of the queue is statically determined • Removing a customer is very efficient

  45. Ring Buffers tail head

  46. An Example typedef struct queue { void *array[MAXSIZE]; int head; int tail; } *queueT; array: head: 0 tail: 0 array: a head: 0 tail: 1 array: a b head: 0 tail: 2 array: a b c head: 0 tail: 3 array: b c head: 1 tail: 3

  47. An Example queueT newQueue(void) { queueT q; q = (queueT) malloc(sizeof(struct queue)); q->head = q->tail = 0; return q; } void freeQueue(queueT q) int queueLength(queueT q) { { free((char *) q); return ((q->tail-q->head) %MAXSIZE) ; } }

  48. An Example void enqueue(queueT q, void *obj) { if (queueLength(q) == MAXSIZE) { error(“enqueue called on a full queue”); } q->array[q->tail++] = obj; q->tail %= MAXSIZE; }

  49. An Example void *dequeue(queueT q) { void *result; int i; if (queueLength(q) == 0) error(“dequeue called on an empty queue”); result = q->array[q->head++]; q->head %= MAXSIZE; return result; }

  50. Third Implementation • A queue is implemented as a linked list and the front of the queue will change dynamically • The length of the queue is dynamically determined • Removing a customer is very efficient

More Related