C - Campos de bits

Suponga que su programa C contiene una serie de variables VERDADERAS / FALSAS agrupadas en una estructura llamada estado, de la siguiente manera:

struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status;

Esta estructura requiere 8 bytes de espacio de memoria, pero en realidad vamos a almacenar 0 o 1 en cada una de las variables. El lenguaje de programación C ofrece una mejor manera de utilizar el espacio de la memoria en tales situaciones.

Si está usando tales variables dentro de una estructura, entonces puede definir el ancho de una variable que le dice al compilador de C que va a usar solo ese número de bytes. Por ejemplo, la estructura anterior se puede reescribir de la siguiente manera:

struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status;

La estructura anterior requiere 4 bytes de espacio de memoria para la variable de estado, pero solo se usarán 2 bits para almacenar los valores.

Si va a utilizar hasta 32 variables cada una con un ancho de 1 bit, entonces también la estructura de estado utilizará 4 bytes. Sin embargo, tan pronto como tenga 33 variables, asignará la siguiente ranura de la memoria y comenzará a usar 8 bytes. Veamos el siguiente ejemplo para comprender el concepto:

#include <stdio.h>
#include <string.h>

/* define simple structure */
struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status1;

/* define a structure with bit fields */
struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status2;
 
int main( ) {
   printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
   printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
   return 0;
}

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

Memory size occupied by status1 : 8
Memory size occupied by status2 : 4

Declaración de campo de bits

La declaración de un campo de bits tiene la siguiente forma dentro de una estructura:

struct {
   type [member_name] : width ;
};

La siguiente tabla describe los elementos variables de un campo de bits:

No Señor. Elemento y descripción
1

type

Un tipo entero que determina cómo se interpreta el valor de un campo de bits. El tipo puede ser int, firmado int o unsigned int.

2

member_name

El nombre del campo de bits.

3

width

El número de bits en el campo de bits. El ancho debe ser menor o igual que el ancho de bits del tipo especificado.

Las variables definidas con un ancho predefinido se denominan bit fields. Un campo de bits puede contener más de un bit; por ejemplo, si necesita una variable para almacenar un valor de 0 a 7, puede definir un campo de bits con un ancho de 3 bits de la siguiente manera:

struct {
   unsigned int age : 3;
} Age;

La definición de estructura anterior le indica al compilador de C que la variable age va a usar solo 3 bits para almacenar el valor. Si intenta utilizar más de 3 bits, no le permitirá hacerlo. Probemos con el siguiente ejemplo:

#include <stdio.h>
#include <string.h>

struct {
   unsigned int age : 3;
} Age;

int main( ) {

   Age.age = 4;
   printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
   printf( "Age.age : %d\n", Age.age );

   Age.age = 7;
   printf( "Age.age : %d\n", Age.age );

   Age.age = 8;
   printf( "Age.age : %d\n", Age.age );

   return 0;
}

Cuando se compila el código anterior, se compilará con una advertencia y cuando se ejecute, producirá el siguiente resultado:

Sizeof( Age ) : 4
Age.age : 4
Age.age : 7
Age.age : 0