C - Campos de bits

Suponha que seu programa C contenha uma série de variáveis ​​TRUE / FALSE agrupadas em uma estrutura chamada status, como segue -

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

Essa estrutura requer 8 bytes de espaço de memória, mas na verdade, vamos armazenar 0 ou 1 em cada uma das variáveis. A linguagem de programação C oferece uma maneira melhor de utilizar o espaço da memória em tais situações.

Se você estiver usando tais variáveis ​​dentro de uma estrutura, então você pode definir a largura de uma variável que diz ao compilador C que você usará apenas aquele número de bytes. Por exemplo, a estrutura acima pode ser reescrita da seguinte forma -

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

A estrutura acima requer 4 bytes de espaço de memória para a variável de status, mas apenas 2 bits serão usados ​​para armazenar os valores.

Se você usar até 32 variáveis, cada uma com largura de 1 bit, a estrutura de status também usará 4 bytes. Porém, assim que você tiver 33 variáveis, ele alocará o próximo slot da memória e começará a usar 8 bytes. Vamos verificar o seguinte exemplo para entender o conceito -

#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;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

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

Declaração de campo de bits

A declaração de um campo de bits tem a seguinte forma dentro de uma estrutura -

struct {
   type [member_name] : width ;
};

A tabela a seguir descreve os elementos variáveis ​​de um campo de bits -

Sr. Não. Elemento e descrição
1

type

Um tipo inteiro que determina como o valor de um campo de bits é interpretado. O tipo pode ser int, int assinado ou int não assinado.

2

member_name

O nome do campo de bits.

3

width

O número de bits no campo de bits. A largura deve ser menor ou igual à largura em bits do tipo especificado.

As variáveis ​​definidas com uma largura predefinida são chamadas bit fields. Um campo de bits pode conter mais de um único bit; por exemplo, se você precisa de uma variável para armazenar um valor de 0 a 7, você pode definir um campo de bit com uma largura de 3 bits da seguinte maneira -

struct {
   unsigned int age : 3;
} Age;

A definição da estrutura acima instrui o compilador C de que a variável idade usará apenas 3 bits para armazenar o valor. Se você tentar usar mais de 3 bits, isso não permitirá que você faça isso. Vamos tentar o seguinte exemplo -

#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;
}

Quando o código acima for compilado, ele será compilado com um aviso e, quando executado, produzirá o seguinte resultado -

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