C - Champs de bits

Supposons que votre programme C contienne un certain nombre de variables TRUE / FALSE regroupées dans une structure appelée status, comme suit -

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

Cette structure nécessite 8 octets d'espace mémoire mais en réalité, nous allons stocker 0 ou 1 dans chacune des variables. Le langage de programmation C offre une meilleure façon d'utiliser l'espace mémoire dans de telles situations.

Si vous utilisez de telles variables dans une structure, vous pouvez définir la largeur d'une variable qui indique au compilateur C que vous n'utiliserez que ce nombre d'octets. Par exemple, la structure ci-dessus peut être réécrite comme suit -

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

La structure ci-dessus nécessite 4 octets d'espace mémoire pour la variable d'état, mais seuls 2 bits seront utilisés pour stocker les valeurs.

Si vous utilisez jusqu'à 32 variables chacune avec une largeur de 1 bit, alors la structure d'état utilisera également 4 octets. Cependant, dès que vous avez 33 variables, il allouera le prochain slot de la mémoire et il commencera à utiliser 8 octets. Vérifions l'exemple suivant pour comprendre le concept -

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

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

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

Déclaration de champ de bits

La déclaration d'un champ de bits a la forme suivante à l'intérieur d'une structure -

struct {
   type [member_name] : width ;
};

Le tableau suivant décrit les éléments variables d'un champ de bits -

N ° Sr. Élément et description
1

type

Un type entier qui détermine la manière dont la valeur d'un champ de bits est interprétée. Le type peut être int, signed int ou unsigned int.

2

member_name

Le nom du champ de bits.

3

width

Le nombre de bits dans le champ de bits. La largeur doit être inférieure ou égale à la largeur en bits du type spécifié.

Les variables définies avec une largeur prédéfinie sont appelées bit fields. Un champ de bits peut contenir plus d'un bit; par exemple, si vous avez besoin d'une variable pour stocker une valeur de 0 à 7, vous pouvez définir un champ de bits d'une largeur de 3 bits comme suit -

struct {
   unsigned int age : 3;
} Age;

La définition de structure ci-dessus indique au compilateur C que la variable age n'utilisera que 3 bits pour stocker la valeur. Si vous essayez d'utiliser plus de 3 bits, cela ne vous permettra pas de le faire. Essayons l'exemple suivant -

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

Lorsque le code ci-dessus est compilé, il sera compilé avec un avertissement et lorsqu'il est exécuté, il produit le résultat suivant -

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