Union in C programming


Advertisements

Share



Learn C union declaration, initilization, array of unions, typedef, size of union, passing union or union pointer to function, function returning union or union pointer with examples, demonstrations.

Difference between struct,union

  • Like structure, union is another derived data type in C and consists of one or more members.
  • Structs allocate enough space to store all of the members in the struct. The first member is stored at the beginning of the struct, the second is stored after that, and so on.
  • To demonstrate abobe feature let's write a small program as shown below

    
    #include "stdio.h"
    struct S{
      char c;
      int i;
    };
    union U{
      char c;
      int i;
    };
    void main()
    {
      printf("sizeof struct S:%d,sizeof union U:%d\n", sizeof(struct S),sizeof(union U));
    }
    
    Program output:
    ===============
    $ gcc prog,c
    $ ./a.out
    sizeof struct S:8,sizeof union U:4
    $
    

    Endianness using union

  • The members of an union share the same storage. So union can store only one of its members at a time, but not all members simultaneously. During union initialization, the compiler allocates only enough space for the largest of the members which overlay each other within this space. As a result, assigning a new value in the member alters the values of the other members as well.
  • Let's look at the below program to demonstrate this feature.

    
    #include "stdio.h"
    union U{
      char c;
      int i;
    };
    void main()
    {
      union U one;
      printf("Char started at Address %x and integer started at Address %x\n",&one.c,&one.i);
      one.i = 0x11223344;
      printf("Add:%x,value:%x\nAdd:%x,value:%x\nAdd:%x,value:%x\nAdd:%x,value:%x\n",&one.c,one.c,(&one.c)+1,*((&one.c)+1),(&one.c)+2,*((&one.c)+2),(&one.c)+3,*((&one.c)+3));
      if(one.c == 0x44){
        printf("Little Endian\n");
      }else{
        printf("Big Endian\n");
      }
    }
    
    Program output:
    ===============
    $ gcc prog.c
    $ ./a.out
    Char started at Address 7ef7b20c and integer started at Address 7ef7b20c
    Add:7ef7b20c,value:44
    Add:7ef7b20d,value:33
    Add:7ef7b20e,value:22
    Add:7ef7b20f,value:11
    Little Endian
    $
    

    Let's analyze the above program

  • We have created one an instance of union U and using that instance we have printed the address of char variable c and int variable i. Notice in the program output that they are same. What does it mean? If you change one member the other member will change automatically because they are stored in the same starting address. The difference is that int will occupy 4 bytes compared to char which will occupy only 1 byte.

    We wrote hex number 0x11223344 into int i with 0x44 as LSB byte and 0x11 as MSB byte. Then, we have printed the address of char member c and its content. You will notice that char c content has changed along with the content of next bytes as well.

    A machine is Little Endian if LSB byte is written at the lower address in memory and Big Endian if MSB byte is written at the lower memory location in memory. As we could check the content of character variable to know the endianness of the machine.

    Break up larger data items

    Let's write a small program to break up all bytes from an integer given by user.

    
    #include "stdio.h"
    union {
        unsigned int n;
        unsigned char c[4];
    } data;
    void main(){
        int nRead = 0x11223344;
        data.n = nRead;
        for( int i = 0; i < 4; i++ )
        {
        	printf( "Byte number %d of %ud in decimal %d in hex:%x\n", i, nRead, data.c[i], data.c[i] );
        }
    }
    
    Program output:
    ===============
    $ gcc prog.c
    $ ./a.out
    Byte number 0 of 287454020d in decimal 68 in hex:44
    Byte number 1 of 287454020d in decimal 51 in hex:33
    Byte number 2 of 287454020d in decimal 34 in hex:22
    Byte number 3 of 287454020d in decimal 17 in hex:11
    $
    

    Union real world application

    Let's look at how an union can be used actually to save memory space in a real world application.

    
    #include "stdio.h"
    typedef struct Flight {
    	enum { PASSENGER, CARGO } type;
        union {
            int npassengers;
            double tonnages;
        } cargo;
    } Flight;
    void main()
    {
        Flight flights[1000];
        flights[ 42 ].type = PASSENGER;
        flights[ 42 ].cargo.npassengers = 150;    
        flights[ 20 ].type = CARGO;
        flights[ 20 ].cargo.tonnages = 356.78;
    }
    

    In the above program you will use union to identify flight type as PASENGER or CARGO and set the variables accordingly. A flight can either be PASSENGER or CARGO but not both. Also if it is a PASSENGER type it will have no of passengers on board, tonnages variable will not be applicable for it. Similarly if it is a PASSENGER type it will have no of tonnes loaded on the flight, npassengers variable will not be applicable for it. In this situation you will use an union not a struct.

    Exercises, Solutions

    High
    High
    High
    Medium
    High
    Medium
    High

    Want to contribute a new article? Write and upload your article information .
    Share
  •  Articles

     C Programming

     Linux Software

     Test your skills:online tests

     C Programming

     Python Programming

     Linux Software

     Quantitative Aptitude

     Embedded System Software

     Search Code Snippets

     Popular C search examples

     Popular C search MCQs