Conocemos lo que es un struct: un dato formado por varios “trozos” de información de distinto tipo. Pero C también tiene dos tipos especiales de “struct”, de manejo más avanzado. Son las uniones y los campos de bits.
Una unión recuerda a un “struct” normal, con la diferencia de que sus “campos” comparten el mismo espacio de memoria:
union {
char letra; /* 1 byte */
int numero; /* 4 bytes */
} ejemplo;
En este caso, la variable “ejemplo” ocupa 4 bytes en memoria (suponiendo que estemos trabajando en un compilador de 32 bits, como lo son la mayoría de los de Windows y Linux). El primer byte está compartido por “letra” y por “numero”, y los tres últimos bytes sólo pertenecen a “numero”.
Si hacemos
ejemplo.numero = 25;
ejemplo.letra = 50;
printf("%d", ejemplo.numero);
Veremos que “ejemplo.numero” ya no vale 25, puesto que al modificar “ejemplo.letra” estamos cambiando su primer byte. Ahora “ejemplo.numero” valdría 50 o un número mucho más grande, según si el ordenador que estamos utilizando almacena en primer lugar el byte más significativo o el menos significativo.
Un campo de bits es un elemento de un registro (struct), que se define basándose en su tamaño en bits. Se define de forma muy parecida (pero no igual) a un "struct" normal, indicando el número de bits que se debe reservar a cada elemento:
struct campo_de_bits {
int bit_1 : 1;
int bits_2_a_5 : 4;
int bit_6 : 1;
int bits_7_a_16 : 10;
} variableDeBits;
Esta variable ocuparía 1+4+1+10 = 16 bits (2 bytes). Los campos de bits pueden ser interesantes cuando queramos optimizar al máximo el espacio ocupado por nuestro datos.