Suppose we are interested in creating a histogram of people’s birthday months. We have data with birthdays of people which can be fetched using a given function. We would need an array of character strings to store the names of all the months and an array of integers to store the frequency / count. We could possibly define two arrays to be used in parallel:
char *months[12]; int count[12];
A more suitable representation here would be an array of structure with month name and frequency / count as members.
struct bucket { char *month; int count; } histogram[12];
We could also write the above as:
struct bucket { char *month; int count; }; struct bucket histogram[12];
histogram would have a constant set of month names, so it may be convenient to make it an external variable and initialise it once when it is defined.
struct bucket { char *month; int count; } histogram[] = { { "January": 0 }, { "February": 0 }, { "March": 0 }, { "April": 0 }, { "May": 0 }, { "June": 0 }, { "July": 0 }, { "August": 0 }, { "September": 0 }, { "October": 0 }, { "November": 0 }, { "December": 0 }, };
As seen previously, the array size is left empty and will be computed based on the number of entries in the initialiser. Also, the inner curly braces are optional when the initialisers are simple variables or character strings and when all are present, as is the case here.
Although the number of items in histogram is obvious here, in other cases of structure arrays, especially the ones that could change, instead of counting it manually, we could calculate this by using:
C provides a compile-time unary operator sizeof that can be used to compute the size of any object. The expressions
sizeof object
and
sizeof(type name)
yield an unsigned integer (of type size_t defined in stddef.h) equal to the size of the specified object or type in bytes. Here, the object could be a variable or array or structure. The type name could be a basic type like int or double or a derived type like a structure or a pointer.