A major use for pointers is to enable dynamic structures like linked lists and trees. Recall from earlier courses how these are essentially recursive data structures:
A linked list is either
A binary tree is either
Notice two things: The recursion in the definitions. And the fact that we need to have references to our own type of node in order to define our node! structs exist in C and are essentially objects containing several fields of data. Unlike objects in proper OO languages, C's structs are simply data-- we cannot encapsulate methods within objects as we can in, say, Java. typedef in C allows for definitions of recursive data structures.
Here's code to enable linked lists of words:
typedef struct listnode {char *word; struct listnode *next;} List, *ListP; ListP malloc(int); ListP construct(char *data, ListP n) { ListP new = malloc(sizeof(List)); new->word = data; new->next = n; return new; } char *head(ListP lp) { return lp->word; } ListP rest(ListP lp) { return lp->next; }
head(l) returns the first word in the list l. rest(l) returns the whole of list l less the first node. construct(w, l) constructs a larger list by adding a node containing word w to the front of the existing list l.
This file contains most of the code you need to read a file, store the unique words in a linked list, reverse the list, print it. It contains an even terser version of strcomp().
Before we leave immutable lists, try to figure out the memory allocation that is taking place. Here's a suggestion: