Page Content

Tutorials

What Are The Unions In C And How To Declare It?

Unions in C

One unique type of organization is a union. Similar to a structure, it is a grouping of variables under a common name; these variables, referred to as members, may be of various data kinds. The allocation and utilization of memory, however, is where the main distinction lies.

Every member of a union uses the same storage space. This contrasts with a structure, in which every member has a designated storage space. A union can only store one piece of data at a time as all of its members share the same memory region. Only one member, and hence only one type, can be mentioned at a time. The programmer is in charge of accessing the member that is now stored in the union and maintaining track of whatever type is currently stored there. Implementation-dependent outcomes may arise from referencing the data with an incorrect kind of variable.

The largest member’s size determines the size of a union variable. The compiler allots sufficient storage to hold the largest member along with any alignment-related padding.

When working with several members, unions are mostly utilised to save memory because not all of them are necessary or relevant at the same time. When you need to interpret the same memory place in multiple ways, they are also helpful.

Declaring and Initializing Unions

The union keyword, an optional tag name, and the members enclosed in curly braces {} are used to declare a union type:

union Union_Name {
    data_type member1;
    data_type member2;
    // ...
};

Similar to a structure declaration, a union definition just generates a new type; no memory is reserved until variables are created using the type.

Using the union keyword and the union name, you can declare union variables either while defining the union or independently:

If a union variable has an external or static storage class, it can be initialized. It is possible to initialize only one member at a time. The first member of the union is given the initialization value.

Accessing Union Members

The same process that is used to access members of a structure is used to access individual union members.

  • Use the dot operator (.) if you have a union variable: union_variable.member_name
  • Use the arrow operator (->) if you have a pointer to a union: pointer_to_union -> member_name

Code Example Illustrating Unions

The definition, declaration, initialization, and member access of a union are illustrated in this example, which also emphasises that members share memory:

#include <stdio.h>
// Define a union type called 'value_holder'
// It can hold either an integer or a floating-point number
union value_holder {
    int     i;
    float   f;
}; // Definition creates the type, no memory yet
int main(void) {
    // Declare a union variable 'data' of type union value_holder
    // Memory is allocated here, enough for the largest member (float) 
    union value_holder data;
    // Initialize the 'data' union variable
    // Note: Can only initialize the first member (int i) directly 
    // If we tried to initialize with a float here, it might cause a warning or error 
    // union value_holder data = { 123 }; // Valid: initializes data.i to 123
    // --- Demonstrating shared memory ---
    // Put an integer value into the 'i' member
    data.i = 65; // Use the dot operator for the union variable
    printf("After storing integer (65):\n");
    printf("Accessing as int: %d\n", data.i); // Accessing the int member
    // Accessing as float - interpreting the same memory as a float 
    // The result is implementation-dependent and likely garbage 
    printf("Accessing the same memory as float: %f\n\n", data.f);
    // Now, put a float value into the 'f' member
    data.f = 98.6; // This overwrites the previous integer value in the shared memory 
    printf("After storing float (98.6):\n");
    // Accessing as float 
    printf("Accessing as float: %f\n", data.f);
    // Accessing as int - interpreting the same memory as an int 
    // The result is implementation-dependent and likely garbage 
    printf("Accessing the same memory as int: %d\n\n", data.i);
    // --- Demonstrating pointer access (same syntax as structures) ---
    union value_holder *data_ptr; // Declare a pointer to the union
    data_ptr = &data; // Point the pointer to the 'data' union variable 
    // Use the arrow operator to access members via the pointer
    data_ptr->i = 100;
    printf("After storing integer (100) using pointer:\n");
    printf("Accessing via pointer as int: %d\n", data_ptr->i);
    printf("Accessing the same memory via pointer as float: %f\n\n", data_ptr->f); // Implementation-dependent
    return 0;
}

Output:

After storing integer (65):
Accessing as int: 65
Accessing the same memory as float: 0.000000
After storing float (98.6):
Accessing as float: 98.600000
Accessing the same memory as int: 1120000026
After storing integer (100) using pointer:
Accessing via pointer as int: 100
Accessing the same memory via pointer as float: 0.000000

Explanation of the Code Example:

  • An int or a float can be stored in the union value_holder that we define.
  • This union type variable data is declared. The compiler allots RAM for data up to the greatest member’s size, which on most platforms is float.
  • The integer 65 is first stored in data.i. Because the bit pattern that represents the integer 65 is being interpreted as a floating-point number, the result is trash when we attempt to print data.f.
  • The float 98.6 is then saved in data.f. The memory that previously contained the integer is overwritten as a result. The bit pattern that represents the float 98.6 is being interpreted as an integer, so when we try to print data.i later, the result is garbage. This demonstrates unequivocally that the members have similar memories.
  • Next, we use the address-of operator & to make a pointer data_ptr to union value_holder point to data.
  • We show how to use the arrow operator -> to access and edit members, confirming that the syntax is the same as for structures.

Because the shared memory’s meaning varies depending on the implementation, the precise garbage values that are reported will vary depending on the system and compiler.

You can also read How To Use Structures With Functions?

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.
Index