The union
type is identical to the struct type, except that all fields share the same memory position. Therefore, the size of a union is the size of the largest field it contains. In the following code, this is the integer field, which is four bytes.
union mix {
char c; /* 1 byte */
short s; /* 2 bytes */
int i; /* 4 bytes */
};
Given this memory sharing, the union type can only be used to store one value at a time, because changing one field will overwrite the value of the others.
int main(void) {
union mix m;
m.c = 0xFF; /* set first 8 bits */
m.s = 0; /* reset first 16 bits */
}
The benefit of a union, in addition to efficient memory usage, is that it provides multiple ways of using the same memory location. For example, the following union has three data members that allow access to the same group of four bytes in different ways.
union mix {
char c[4]; /* 4 bytes */
struct { short hi, lo; } s; /* 4 bytes */
int i; /* 4 bytes */
} m;
The int field accesses all four bytes at once, the struct two bytes at a time, and the char array allows each byte to be referenced individually. The bit pattern for this is illustrated in the next example. Keep in mind that the internal order of bytes for primitive data types is not defined in C. Because of this, the order of the four bytes that make up the int may be reversed on some platforms.
m.i=0xFF00F00F; /* 11111111 00000000 11110000 00001111 */
m.s.lo; /* 11111111 00000000 */
m.s.hi; /* 11110000 00001111 */
m.c[3]; /* 11111111 */
m.c[2]; /* 00000000 */
m.c[1]; /* 11110000 */
m.c[0]; /* 00001111 */