Structures

If you completed one of the “number of occurrences” exercise (either the naive approach or the hash table approach), you probably used two arrays to storing information about your words:

char *words[N] = { NULL };
int counts[N] = { 0 };

But what we really wanted to store is an array of composite types: pairs (word, count). In C, this can be achieved by introducing a struct type:

struct word_count {
  char *word;
  int count;
}; /* notice the semicolon */

We call word and count fields. To access the fields of the struct, we use .:

struct word_count wc;
wc.word = strdup("test");
wc.count = 1;

Now, instead of making two unrelated arrays, we can create one array of type struct word_count:

struct word_count words[N] = { { NULL, 0 } };

Note that I'm using an incomplete initialized here and everywhere: as we discussed when we talked about arrays, incomplete initializer initializes the remaining elements to their zero values.

An important note for those who have some experience with C++: in C the struct name by itself is not a valid type name, this is a big difference between the languges. You cannot use just word_count, you must write struct word_count (or use the typedef keyword which we'll discuss later).

Let's practice working with structs. Take your solution to either of the “number of occurrences” exercises, and change it from using two arrays to using one array of structs:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 2000

struct word_count {
	char *word;
	int count;
};

int main() {
	struct word_count words[N] = { { NULL, 0 } };

  /* Your code here! */
}

The struct is always allocated in memory as one block; its size is either equal or just a little bit greater than the sum of the sizes of its elements. Why bigger? That's because the compiler might need to insert some padding between elements; we won't discuss it now in detail, just know that if you want to know the size of your struct in bytes, use sizeof on the whole struct and don't try to guess the size by looking at the struct fields.

You will see the real power of the structs on the next page, when we start allocating memory for structs, which will allow us to build interesting data structures in memory. Stay tuned!

© Alexander Fenster (contact)