Учебники

C — битовые поля

Предположим, что ваша C-программа содержит несколько переменных TRUE / FALSE, сгруппированных в структуру, называемую status, следующим образом:

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

Эта структура требует 8 байт памяти, но в действительности мы собираемся хранить 0 или 1 в каждой из переменных. Язык программирования C предлагает лучший способ использовать пространство памяти в таких ситуациях.

Если вы используете такие переменные внутри структуры, вы можете определить ширину переменной, которая сообщает компилятору C, что вы собираетесь использовать только это количество байтов. Например, приведенная выше структура может быть переписана следующим образом:

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

Приведенная выше структура требует 4 байта пространства памяти для переменной состояния, но только 2 бита будут использоваться для хранения значений.

Если вы будете использовать до 32 переменных, каждая из которых имеет ширину 1 бит, то в структуре состояния также будет использоваться 4 байта. Однако, как только у вас будет 33 переменные, он выделит следующий слот памяти и начнет использовать 8 байтов. Давайте проверим следующий пример, чтобы понять концепцию —

Live Demo

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

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

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

Объявление битового поля

Объявление битового поля имеет следующую форму внутри структуры:

struct {
   type [member_name] : width ;
};

В следующей таблице описаны переменные элементы битового поля —

Sr.No. Элемент и описание
1

тип

Целочисленный тип, который определяет, как интерпретируется значение битового поля. Тип может быть int, подписанный int или беззнаковый int.

2

имя участника

Название битового поля.

3

ширина

Количество битов в битовом поле. Ширина должна быть меньше или равна битовой ширине указанного типа.

тип

Целочисленный тип, который определяет, как интерпретируется значение битового поля. Тип может быть int, подписанный int или беззнаковый int.

имя участника

Название битового поля.

ширина

Количество битов в битовом поле. Ширина должна быть меньше или равна битовой ширине указанного типа.

Переменные, определенные с предопределенной шириной, называются битовыми полями . Битовое поле может содержать более одного бита; например, если вам нужна переменная для хранения значения от 0 до 7, вы можете определить битовое поле шириной 3 бита следующим образом:

struct {
   unsigned int age : 3;
} Age;

Приведенное выше определение структуры указывает компилятору C, что переменная age будет использовать только 3 бита для хранения значения. Если вы попытаетесь использовать более 3 бит, то это не позволит вам сделать это. Давайте попробуем следующий пример —

Live Demo

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

Когда приведенный выше код компилируется, он компилируется с предупреждением, а при выполнении выдает следующий результат: