Submitted by tushar pramanick on Sun, 03/10/2013 - 21:48

Unions Versus Structures

You might notice that in Listing 20.1, I assigned a value to one member of the dish union, and then immediately printed out the assigned value before I moved to the next union member. In other words, I didn't assign values to all the union members together before I printed out each assigned value from each member in the union.

I did this purposely because of the reason that is explained in the following section. So keep reading. (In exercise 1 at the end of this lesson, you'll see a different output when you rewrite the program in Listing 20.1 by exchanging the orders between the statements in lines 15
and 17.)

 

Initializing a Union

As mentioned earlier in this lesson, data items in a union are overlaid at the same memory location. In other words, the memory location of a union is shared by different members of the union at different times. The size of a union is equal to the size of the largest data item in the list of the union members, which is large enough to hold any members of the union, one at a time. Therefore, it does not make sense to initialize all members of a union together because the value of the latest initialized member overwrites the value of the preceding member. You initialize a member of a union only when you are ready to use it. The value contained by a union is the value that is latest assigned to a member of the union.

For instance, if we declare and define a union on a 16-bit machine (that is, the int data type is 2 bytes long) like this:

union u {
   char ch;
   int x;
} a_union;


then the following statement initializes the char variable ch with the character constant `H':

a_union.ch = `H';

and the value contained by the a_union union is the character constant `H'. However, if the int variable x is initialized by the following statement:

 a_union.x = 365;

then the value contained by the a_union union becomes the value of 365. Figure 20.1 demonstrates the content change of the union during the two initializations.


Figure 20.1. The content of the a_union union is the same as the content assigned to one of its members.

According to the ANSI C standard, a union can be initialized by assigning the first union member with a value. For instance, in the following statement:

union u {
   char ch;
   int x;
} a_union = {`H'};


the a_union union is said to be initialized because the character constant `H' is assigned to the first union member, ch.

If the first member of a union is a structure, the entire structure has to be initialized with a list of values before the union can be said to have been initialized.

Let's see what will happen if we try to assign values to all members of a union together. Listing 20.2 gives such an example.

TYPE
Listing 20.2. The members of a union share the same memory location.


1:  /* 20L02.c:  Memory sharing in unions */
2:  #include <stdio.h>
3:
4:  main(void)
5:  {
6:     union employee {
7:        int start_year;
8:        int dpt_code;
9:        int id_number;
10:    } info;
11:
12:    /* initialize start_year */
13:    info.start_year = 1997;
14:    /* initialize dpt_code */
15:    info.dpt_code = 8;
16:    /* initialize id */
17:    info.id_number = 1234;
18:
19:    /* display content of union */
20:    printf("Start Year:  %d\n", info.start_year);
21:    printf("Dpt. Code:   %d\n", info.dpt_code);
22:    printf("ID Number:   %d\n", info.id_number);
23:
24:    return 0;
25: }


After the executable 20L02.exe is created and executed, the following output is displayed on the screen:

OUTPUT

C:\app>20L02
Start Year:  1234
Dpt. Code:   1234
ID Number:   1234
C:\app>

As you can see in Listing 20.2, a union called info has three int variable members, start_year, dpt_code, and id_number. (See lines 6_10.) Then, these three union members are assigned with different values consecutively in lines 13, 15, and 17. And in lines 20_22, we try to print out the values assigned to the three members. However, the output shows that every member in the info union has the same value, 1234, which is the integer assigned to the third member of the union, id_number. Note that id_number is the member that is assigned with 1234 last; the info union does hold the latest value assigned to its members.
The Size of a Union

You've been told that the members of a union share the same memory location. The size of a union is the same as the size of the largest member in the union.

In contrast with a union, all members of a structure can be initialized together without any overwriting. This is because each member in a structure has its own memory storage. The size of a structure is equal to the sum of sizes of its members instead of the size of the largest member.

How do I know whether all these are true? Well, I can prove it by measuring the size of a union or a structure. Listing 20.3 contains a program that measures the size of a union as well as the size of a structure. The structure has exactly the same members as the union.

TYPE
Listing 20.3. Measuring the size of a union.


1:  /* 20L03.c The size of a union */
2:  #include <stdio.h>
3:  #include <string.h>
4:
5:  main(void)
6: {
7:    union u {
8:        double x;
9:        int y;
10:    } a_union;
11:
12:    struct s {
13:       double x;
14:       int y;
15:    } a_struct;
16:
17:    printf("The size of double: %d-byte\n",
18:            sizeof(double));
19:    printf("The size of int:    %d-byte\n",
20:            sizeof(int));
21:
22:    printf("The size of a_union:  %d-byte\n",
23:            sizeof(a_union));
24:    printf("The size of a_struct: %d-byte\n",
25:            sizeof(a_struct));
26:
27:    return 0;
28: }


The compiler on your machine may generate several warning messages, something like "unreferenced local variables." This is because the a_union union and the a_struct structure are not initialized in the program. You can ignore the warning messages. The following output is displayed on the screen after the executable 20L03.exe is created and executed:

OUTPUT

C:\app>20L03
The size of double: 8-byte
The size of int:    2-byte
The size of a_union:  8-byte
The size of a_struct: 10-byte
C:\app>

ANALYSIS

The purpose of the program in Listing 20.3 is to show the difference between a union memory allocation and a structure memory allocation, although both the union and the structure consist of the same members.

A union, called a_union, is defined in lines 7_10; it has two members, a double variable x and an int variable y. In addition, a structure, called a_structure and defined in lines 12_15, also consists of two members, a double variable x and an int variable y.

The statements in lines 17_20 first measure the sizes of the double and int data types on the host machine. For instance, on my machine, the size of the double data type is 8 bytes long and the int data type is 2 bytes long.

Then lines 22_25 measure the sizes of the a_union union and the a_structure structure, respectively. From the output, we see that the size of a_union is 8 bytes long. In other words, the size of the union is the same as the size of the largest member, x, in the union.

The size of the structure, on the other hand, is the sum of the sizes of two members, x and y, in the structure (10 bytes in total).

Comments

Related Items

ভালো C প্রোগ্রামিং কিভাবে করবে ?

ক্লাস 24 : তুমি এখন যে গুলি করতে পারো

CLASS 24: What You Can Do Now

You're now in the last chapter of this book. In this lesson you'll learn more about the C language from the following topics:

C Preprocessor এর ব্যবহার ও উপযোগিতা

In Chapter 2, "Writing Your First C Program," you learned how to use the #include preprocessor directive to include C header files. Since then, the #include directive has been used in every program in this book.

C প্রোগ্রামিং ও অ্যাডভান্স File অপারেশন

In last hour's lesson you learned the basics of reading and writing disk data files. In this lesson you'll learn more about communication with disk data files. The main topics discussed in this hour are

    Random access to files
    Reading or writing binary data

C প্রোগ্রামিং ও File অপারেশন

In Chapter 5, "Reading from and Writing to Standard I/O," you learned how to read or write characters through standard input or output. In this lesson you'll learn to read data from or write data to disk files. The following topics are discussed in this lesson:

Unions: বিসদৃশ Data সংগ্রহের অন্য উপায়

In the previous hour's lesson you learned how to store data of different types into structures. In this hour you'll learn another way to collect differently typed data items by using unions. You'll learn about the following topics in this lesson: