Today we’re going to discuss two topics which are rarely taught in a C programming college course, Unions & Enums. One may justify that by saying they are not absolutely necessary for basic knowledge in programming, or that these topics are rarely asked in interviews. But if you become a professional C developer, you’ll have extensive use of them. These are particularly useful in low level programming, like with embedded systems and robotics.
Unions: Unions are user-defined data type in C, which is used to store a collection of different kinds of data, just like a structure. However, with unions, you can only store information in one field at any one time. A structure will take up memory which will be equal to the sum of memory required by all member variables. But a union will take up only the memory required by the member variable with highest memory requirement.
Enums: Enumeration or enum for short, is a user defined data type in C, which is mainly used to assign names or aliases to integral constants, which in turn make a program easy to read and maintain. Its syntax looks similar to structures and unions, but fundamentally it just holds an int variable, which can only have some specific values, and these values have aliases which help the programmer keep track of things. The size of an enum is always equal to the size of int, i.e. 4 bytes.
Lets see a couple of simple example programs using unions & enums.
Unions can have member variables of different types, but only one member can be assigned a value at one time. For example if we have a union of students, like we had structure of students in the previous blog, it can use either the name, marks or grade variable at one time. If we have a char array of 10 bytes for name, int array of 5 integers, i.e. 20 bytes for marks, and a single byte for grade, a student structure will take up 31 bytes, whereas a student union will take up only 20 bytes. So if we enter marks for a student union, its name and grade variables will have garbage value. Thus unions can’t be used to store/process records of data like structures. But unions can have other uses.
Lets consider a scenario where a certain stream of data is written in memory. While reading, the data as a whole and also its individual bits/bytes makes sense. These scenarios often occur working with microprocessors/microcontrollers i.e. at a low level programming, where individual bits/bytes need to be analysed. If we create a union with a bigger data variable of appropriate data-type, and parts variables of smaller data-types to store parts of the data, writing on the data variable will result in parts getting populated.
The following example is an illustration of this idea.
In this program, we create a union called data in line no.4 and assign two member variables, an unsigned int variable called data and a structure called parts which in turn has two unsigned short integer variables (2 bytes long each), called LSB & MSB. Unsigned variable types doesn’t contain negative values, so they have the maximum value which is double of what normal int variables have. We create a varibale p of the parts structure and a variable d1 of the data union.
To simulate a stream of incoming data, we prompt the user to enter the data, which we store in the data variable of d1. We access members of unions in the same manner as we access members of structure. The variable d1 is 4bytes long since the largest member is an unsigned int. So the structure variable parts overlaps on the same physical memory as data. So the 4 bytes of data is also present as two separate 2byte variables of parts which we can access similarly with the dot operator.
Two extreme cases are shown in the output by entering the highest possible value (all 32 bits 1s) of an unsigned int which results in both MSB & LSB to have highest possible unsigned short integer values, and the highest possible unsigned short integer value (lower 16bits 1s and upper 16bits 0s), which results in MSB having a value of 0.
Enums have only 1 member variable of int type, but its possible values can be given names/aliases that convey certain meaning to the programmer. Lets say the programmer is working on a calendar application and has to check which day it is. Rather than creating a char array of atleast 8 characters, and assigning string values every now and then, an enum can be created which will have aliases for values 0 to 6 ( or 1 to 7) for each day of the week. In this manner, days can be incremented or decremented, and in conditional statements their aliases (sunday, monday etc.) can be compared for the programmer’s convenience. This days will be a single variable with only 4bytes of memory requirement.
A more practical use is aliasing status codes. This could help in debugging complicated programs. Lets create an enum datatype returnCode which have aliases PASSED, ERROR and UNDEFINED. By default, the integer values corresponding to these aliases begin from 0 and increment by 1. So PASSED represents 0, ERROR represents 1 and UNDEFINED represents 2. We can change these values in the enum definition with the ‘=’ assignment operator.
Somewhere in the program, the variable code of type enum returnCode is set to a value. Then we can write conditional statements based on this value. But a programmer doesn’t need to memorize what integer corresponds to what status. He can simply refer the string values in the conditional statements. Enums are exclusively used for a programmer’s convenience. As a matter of fact, high level programming languages are made for a programmer’s convenience. So even though they may not seem too compelling to you, they have a lot of use cases where they are extremely useful.
These topics are generally neglected, and in fact they don’t have much use in a beginner’s course. I first encountered enums while learning C#, and very recently came upon unions while researching advanced topics in C. Even so, if you are interested in robotics and/or embedded systems, these concepts will help you a lot. In future we may have a series on embedded system programming, then we’ll revisit these concepts.
You can download the code here.
If you liked this article please comment and show your support and interest so that I’ll be motivated to continue this effort. Like our facebook page if you haven’t already. And if you have any questions please comment. I’ll try to reply all.