Using Structs and Unions together effectively in C
Archive - Originally posted on "The Horse's Mouth" - 2008-03-21 10:58:10 - Graham EllisC's Structs allow you to define a number of different variables, of different types and sizes, sequentially within a collection - you could, for example, define an animal as being:
typedef struct {
char name[15];
float age;
char breed[15];
} animal;
But what if I wanted to have several structs which were similar to each other but not identical - that had many common elements but then varied. An example might be a range of products for sale at a shop, where some of the items are sold in int units (I'll sell you one or two motorbikes, but not 1.5) and others are sold in float units (kgs of apples, for example)?
A Union allows you to define a number of different variables, of different types and sizes, in parallel - i.e. sharing the same memory - within a collection.
Used carefully, a union within a struct can be used to produce a collection that can handle a whole family of slightly varied data types, such as the motorbikes and apples that I described just above. Here are the definitions:
typedef union {
int units;
float kgs;
} amount ;
typedef struct {
char selling[15];
float unitprice;
int unittype;
amount howmuch;
} product;
So that's a product which has a description, a unit price and a type (unit sales or sales per kg). It then has an amount union, allowing the same structure to store either a float or an int as appropriate. But it IS up to the programmer to ensure that the correct use is made of the unioned element.
On the Public C Course that finished yesterday (next one in June!), I wrote a new example to show this use of a union within a structure, and you can see the complete code here (opens in a new window).
You'll note the use of an array of pointers to product structs to allow me to loop through all the products easily, but the the great care I have to take within the loop to ensure that I use the integer or float member of the union as appropriate, based on the unittype variable I have provided for the purpose.
It's no co-incidence that there a great similarity here between the varied members of a combined structure / union and the varied data members of a series of classes that are all inherited from the same base class in C++, Java, etc - indeed, you could describe the use of structs and unions that I talk about here as a do-it-yourself form of inheritance and polymorphism.