主页 Swift UNIX C Assembly Go Plan 9 Web MCU Research Non-Tech

What is Union? Where do I need to use it?

2023-05-12 | C | #Words: 967

In C language, there is a variable called union, which is used to store objects of different types and sizes in different situations. This is very similar to a struct: a struct is a collection of one or more variables.

The declaration method of union is very simple and exactly the same as struct, as follows:

union u_tag {
     int ival;
     char *sval;
}u;

As you can see, the only difference is that the struct in the structure becomes union.

The usage is exactly the same:

//General variables
union_name.val
//pointer
union_pointer->val

The two are so similar, so what is the difference between them? In other words, why make two such similar things? C is not C++, some functions are developed by different groups, and some functions overlap.

The first is the superficial difference. struct and union are completely different in terms of usage purpose. union does not store every variable listed in curly brackets at the same time like struct. If you try the following code

union u_tag {
     int a;
     int b;
}u;

int main()
{
     u.a=1;
     u.b=2;
     printf("u_tag: %d\n", u.a);
     return 0;
}

Then the output result is:

u_tag: 2

The result here is not an error, it’s because union does not output 1 based on the previous u.a=1 like a structure. Since it can only store one kind of data, the following u.b=2 Overwrites the value originally stored in u.

So, variables declared inside union can be understood as a possibility, rather than actual objects or member variables.

And since there is only one value inside union, the same data type is generally not used. As for what data types are currently included, this is something that programmers need to pay attention to when programming. Generally, a variable u_type is used, and then a judgment statement is used to judge the currently included type.

**But the core difference between struct and union is also the reason why union was born: the mechanism of allocating space. **

If you use sizeof() to measure the size of the following two data

union u_tag {
     int ival;
     float fval;
     char *sval;
}u;

struct s_tag {
     int ival;
     float fval;
     char *sval;
} s;

You will find that the size of u_tag is 8 bytes, but the size of s_tag is 16 bytes. This is because union is equivalent to leaving a maximum space for the internally declared data types, while struct leaves its own space for each data type.

On most modern machines, the int type is 4 bytes, the float type is 4 bytes, and the cahr * type is 8 bytes. So u occupies the maximum space, which is 8 bytes, while s each leaves its own space, which is 4+4+8=16 bytes.

So when do you need to use union? First of all, according to its characteristics of storing a kind of data, it can be used to do some general calculations, such as switching between floating point numbers and integers. Secondly, it saves space for the above purpose of use. Although structures can also be used in this case, the above three data types are better if they are twice the size. Because of the memory address allocation mechanism, the addresses of some types of data are specially required. For example, on some machines, int requires an address in an even number of digits.

The following is an example, but the integer address limit is not an even number, but a multiple of 4.

struct s_tag {
     int ival;
     char a;
} s;

The size of this structure is 8 bytes. You can try it yourself to see if it is this size.

And since the compiler reads sequentially, if you write it like this

struct s_tag {
     int a;
     char b;
     int c;
     char d;
} s;

Then the size of this structure is 16 bytes. In this case, data of the same type can be written together to save some space, as follows:

struct s_tag {
     int a;
     int c;
     char b;
     char d;
} s;

In this way, the space occupied by this structure is 12 bytes. And if union is used, the size is always 4 bytes regardless of the order. As the possibilities for data types increase, the need to save space becomes apparent.

​I hope these will help someone in need~