Consider a program which has to accept the person type – student or employee and according to the person type it has to display their class or department. Here the trick is class and department is not valid for either student or employee. Any one of them is valid for the any one of them. That means both class and department will not be active for given person type. This means even though we have two variables in the program to store class and department, we will be using either of them. But as we know already, declaring the variable, occupies some space in the memory. Here in our case when we declare two variables, memory is allocated to both the variables while we are using only one of them. That means memory allocated for the other variable is waste. If a program is very small and is running in our personal computer such kind of memory wastage can be acceptable. But when we write bigger programs where lots of operations are performed, we cannot waste memory space unnecessarily.
In our case above we can use single variable to hold both class and department, like we create person type, where we enter the value as student or employee. Similarly we can enter class id and department id to another variable. But imagine class is of type integer and department is of type character! Now single variable cannot be used. We need separate two variables, but it will create memory wastage here. That means we need two types of variables – int and char as well as memory should not be wasted. How to do achieve this requirement in C ?
In order to address above issue C introduces another type of datatype – union which is similar to structure but different than structure. That means unions are like structure but they are different in allocating memory. In structure, memory is allocated to all of its members – i.e.; it is the sum of memory sizes of individual members of structure. But in union, memory is allocated in such a way that it will not able to hold all of its members within it together. i.e.; memory size of the union is the memory size of largest member of the union. Hence when we create a union to hold both class and department, it will assign memory in such way that size of largest element in this union will be the size of union. Hence it will not have enough space to hold both the member. It can hold either of them at a time. Thus unions will be able to address the need for two variables without wasting the memory space. This powerful feature of unions makes C language even stronger.
Table of Contents
Creating Union
Unions are created in the same way as structures, but by using the keyword ‘union’.
The general syntax for creating unions is shown below :
union union_name{ datatype variable1; datatype variable2; …. datatype variableN; };
Like in structures, union_name is the name of the union, datatype can be any primitive or non-primitive datatype. It can have any number of variables within it, provided only one of them can be accessed at a time.
union category { int intClass; char chrDeptId [10]; };
Above is an example union discussed so far. This union, category contains two elements intClass of integer type and chrDeptId of character type. Even though it has two elements, only one of them will be active at a time. This is because, this union will have only 10 bytes of memory allocated to it (memory size of chrDeptId which is larger compared to intClass). Hence it does not have space to hold both intClass and chrDeptId. This is what our requirement too.
Declaring Unions
Like structure, above is the skeleton of the union. We need to declare union variables using these skeletons of union to access the unions. There are different ways of creating union variables.
While defining Union
While defining the definition / skeleton of the union itself, we can create union variables.
union category { int intClass; char chrDeptId [10]; } student_category, emp_categeory;
Here it creates two union variables student_category and emp_categeory of type category.
After defining Union
We can even create union variables, after defining the structure of union. Latter we can use this union name to create its variables.
union category { int intClass; char chrDeptId [10]; }; union category student_category, emp_categeory;
Using typedef
Typedef can be used to declare the user defined variables. Here if we have to create union variables after defining the union, then we have to specify the full format from ‘union category variable_names’. But if we use typedef at the beginning, it will create a new datatype itself with shorter name. it will replace the whole lengthy declaration to smaller meaningful name.
typedef union category { int intClass; char chrDeptId [10]; }categ; categ student_category, emp_categeory;
Initializing the union elements
Like we said earlier, any one of the member can be active at a time in unions. Hence we can initialize any one of the members of the union.
There are different ways of initializing the elements of unions.
While declaring the union variables
like we initialize the structure elements, we can initialize the union elements too, but any one member of union.
union category { int intClass; char chrDeptId [10]; } student_category = {10}; // this will initialize intClass
Here student _category is the union variable and is initialized its element intClass to 10. Since we have not specified any element name while initializing, it initializes first element.
union category { int intClass; char chrDeptId [10]; }; union category student_category = {10}; // this will initialize intClass
By this method we can only initialize the first element of the union.
By specifying element names
This is another method of initializing the elements of the union. Here we can explicitly specify the member names to which we need to assign values.
union category { int intClass; char chrDeptId [10]; }; union category student_category = {.intClass= 10}; // this will initialize intClass union category emp_categeory = {.chrDeptId= "DEPT_100”}; // this will initialize chrDeptId
OR
union category { int intClass; char chrDeptId [10]; }; union category student_category;
student_category.intClass = 10; // this will initialize intClass
strcpy (student_category.chrDeptId, “DEPT_100”); // this will initialize chrDeptId on union variable student_category, but it will overwrite the value of intClass which will have garbage value now
Accessing the Union Elements
Union elements are accessed in the same way as structure elements. We use ‘.’ to refer its elements.
student_category.intClass = 10; // this will initialize intClass
strcpy (student_category.chrDeptId, “DEPT_100”);
#include #include void main () { union category { int intClass; char chrDeptId [10]; }; union category std_ctg; std_ctg.intClass = 10; // this will initialize intClass printf ("Value of intClass in Student_category is: %d\n", std_ctg.intClass); strcpy (std_ctg.chrDeptId, "DEPT_100"); printf ("Value of chrDeptId in Student_category is: %s", std_ctg.chrDeptId); }
Array of Union
Like array of structures we can also create array of unions and access them in similar way. When array of unions are created it will create each element of the array as individual unions with all the features of union. That means, each array element will be allocated a memory which is equivalent to the maximum size of the union member and any one of the union member will be accessed by array element.
union category { int intClass; char chrDeptId[10]; }; union category catg [10]; // creates an array of unions with 10 elements of union type
Members of array of unions are accessed using ‘.’ operator on union variable name along with the index to specify which array element that we are accessing.
catg[0].intClass = 10;
catg[5].chrDeptId = “DEPT_001”;
Here note that, each element of the union array need not access the same member of the union. It can have any member of the union as array element at any point in time. In above example, first element of the union array accesses intClass while 6th element of union array has chrDeptId as its member.