Основы программирования на С++ для начинающих

Битовые поля в С++

В языке С++ есть возможность задавать элементам структур определённое количество памяти в битах. Например, если необходимо создать структуру данных, соответствующую размеру регистра в каком-либо устройстве. Типом элемента (его называют битовым полем) такой структуры может быть целочисленное (чаще всего типа unsigned) или перечислимое (enum).

Синтаксически битовое поле в структуре определяется следующим образом:
битовые поля с++, структуры в с++ для начинающихНапример:

Мы определили структуру, в которой переменные будут занимать указанное количество бит. 2 + 2 + 4 дает 8 бит (мы выровняли до размера байта). Если в эту структуру дописать еще unsigned short fifth : 5; – уже будет задействовано 2 байта. Во втором байте естественно будет мусор 8 – 5 = 3 бита, которые будут невостребованными.

В отличии от объединений (union) размер битовых полей варьируется, в зависимости от того, сколько бит программист заказал. Если заказано 7 бит (скажем две переменные по 3 бита, и одна – 1 бит), то С++ отведет один байт (8 бит) под эти три переменные.

Если программист закажет 11 бит, то С++ отведет два байта (16 бит). Причем во втором байте будут задействованы только 5 бит, а остальные скорее всего будут, как бесполезный хвост. Поэтому при описании битовых полей следует учитывать такое “выравнивание” до байта. Т.е. распределять в нем переменные так, чтоб каждый бит был востребован. Для выравнивания занимаемой памяти можно использовать неименованные битовые поля.

Приведем еще один короткий пример, в котором битовые поля отводятся под дату и время для демонстрации этой технологии.

Результат:

битовые поля с++, структуры в с++ для начинающих

Как видите, битовые поля хранят дату и время. Занимает эта структура 6 байт, хотя для неё хватит и пяти. И на то есть свои причины: сам компилятор может выравнивать отводимую память до четного числа байтов.

Например если мы заказали 18 бит, компилятор отведет нам не 3 байта, а 4, учитывая что процессор любит работать с байтами, а не с битами. По крайней мере хранить в памяти или своих регистрах процессор предпочитает не биты, а именно байты. Согласно его разрядности: x32 хранят 4 байта, x64 уже 8 байт. Пусть даже из этих байт работа идет только с одним из них, остальные все равно будут подтягиваться.

Небольшой итог: Битовые поля в структурах обычно используются в низкоуровневом программировании, когда работа идет со значениями, способными занимать не байты, а отдельные биты (ввиду того, что значения небольшие).

5 thoughts on “Битовые поля в С++

  1. Дезинформируете людей. Размер
    {
    unsigned short first : 2;
    unsigned short second: 2;
    unsigned short third : 4;
    } равен не 1 байту, а 2

      1. Нет, он всё верно сказал, 2 байта.
        Если поставить unsigned char, то один байт, но вот сейчас два. Поверь в любой ide.
        А если int, то 4; и аналогично для восмибайтовых.

        struct test{
        unsigned long long first : 64;
        unsigned char second: 8;
        }; – имеет размер в 16 байт вместо ожидаемых тобой 9.
        Он выравнивает по размеру типа максимального размера, по видимому.

    1. Align
      try
      #pragma pack(push,1)
      typedef struct{
      unsigned short first :2;
      unsigned short second:2;
      unsigned short third :4;
      } foo;
      #pragma pop()
      Хотя и так 1 байт в мингв мсвц и гцц и смаке

  2. Тут некоторого очень важного уточнения

    Использование такого механизма замедляет программу

    Это связанно с тем, что будет сгенерирован код компилятором для манипуляций с данными(это будут побитовые операции), всё зависит от реализации компилятора(проверяйте его работу в .obj файле(если не знаете о том, что это, то смотрите как компилируется прога))
    В нынешнее время – это может быть не значительным приростом времени, но если частота использования таких данных зашкаливает, то мы получим, возможно, крутую прогу, что требует мало ОЗУ, но точно медленную прогу

    Так что пользуйтесь аккуратней и взвешивайте свое решение

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *