17.2.1. Определение и инициализация наборов битов

Список конструкторов типа bitset приведен в табл. 17.2. Тип bitset — это шаблон класса, который, подобно классу array, имеет фиксированный размер (см. раздел 3.3.6). При определении набора битов следует указать в угловых скобках количество битов, которые он будет содержать:

bitset<32> bitvec(1U); // 32 бита; младший бит 1, остальные биты 0

Размер должен быть указан константным выражением (см. раздел 2.4.4). Этот оператор определяет набор битов bitvec, содержащий 32 бита. Подобно элементам вектора, биты в наборе битов не имеют имен. Доступ к ним осуществляется по позиции. Нумерация битов начинается с 0. Таким образом, биты набора bitvec пронумерованы от 0 до 31. Биты, расположенные ближе к началу (к 0), называются младшими битами (low-order), а ближе к концу (к 31) — старшими битами (high-order).

Таблица 17.2. Способы инициализации набора битов

bitset<n> b; Набор b содержит n битов, каждый из которых содержит значение 0. Это конструктор constexpr (см. раздел 7.5.6) bitset<n> b(u); Набор b содержит копию n младших битов значения u типа unsigned long long. Если значение n больше размера типа unsigned long long, остальные старшие биты устанавливаются на нуль. Это конструктор constexpr (см. раздел 7.5.6) bitset<n> b(s, рos, m, zero, one); Набор b содержит копию m символов из строки s, начиная с позиции pos. Строка s может содержать только символы для нулей и единиц; если строка s содержит любой другой символ, передается исключение invalid_argument. Символы хранятся в наборе b как нули и единицы соответственно. По умолчанию параметр pos имеет значение 0, параметр m — string::npos, zero — '0' и one — '1' bitset<n> b(cp, pos, m, zero, one); Подобен предыдущему конструктору, но копируется символьный массив, на который указывает cp. Если значение m не предоставлено, cp должен указывать на строку в стиле С. Если m предоставлено, то начиная с позиции cp в массиве должно быть по крайней мере m символов, соответствующих нулям или единицам Конструкторы, получающие строку или символьный указатель, являются явными (см. раздел 7.5.4). В новом стандарте была добавлена возможность определять альтернативные символы для 0 и 1.

Инициализация набора битов беззнаковым значением

При использовании для инициализации набора битов целочисленного значения оно преобразуется в тип unsigned long long и рассматривается как битовая схема. Биты в наборе битов являются копией этой схемы. Если размер набора битов превосходит количество битов в типе unsigned long long, то остальные старшие биты устанавливаются в нуль. Если размер набора битов меньше количества битов, то будут использованы только младшие биты предоставленного значения, а старшие биты вне размера объекта набора битов отбрасываются:

// bitvec1 меньше инициализатора; старшие биты инициализатора

// отбрасываются

bitset<13> bitvec1(0xbeef); // биты 1111011101111

// bitvec2 больше инициализатора; старшие биты bitvec2

// устанавливаются в нуль

bitset<20> bitvec2(0xbeef); // биты 00001011111011101111

// на машинах с 64-битовым long long, 0ULL - это 64 бита из 0,

// a ~0ULL - 64 единицы

bitset<128> bitvec3(~0ULL); // биты 0...63 - единицы; 63...121 - нули

Инициализация набора битов из строки

Набор битов можно инициализировать из строки или указателя на элемент в символьном массиве. В любом случае символы непосредственно представляют битовую схему. Как обычно, при использовании строки для представления числа символы с самыми низкими индексами в строке соответствуют старшим битам, и наоборот:

bitset<32> bitvec4("1100"); // биты 2 и 3 - единицы, остальные - 0

Если строка содержит меньше символов, чем битов в наборе, старшие биты устанавливаются в нуль.

Соглашения по индексации строк и наборов битов прямо противоположны: символ строки с самым высоким индексом (крайний правый символ) используется для инициализации младшего бита в наборе битов (бит с индексом 0). При инициализации набора битов из строки следует помнить об этом различии.

Необязательно использовать всю строку в качестве исходного значения для набора битов, вполне можно использовать часть строки:

string str("1111111000000011001101");

bitset<32> bitvec5(str, 5, 4); // четыре бита, начиная с str[5] - 1100

bitset<32> bitvec6(str, str.size()-4); // использует четыре последних

                                       // символа

Здесь набор битов bitvec5 инициализируется подстрокой str, начиная с символа str[5], и четырьмя символами далее. Как обычно, крайний справа символ подстроки представляет бит самого низкого порядка. Таким образом, набор bitvec5 инициализируется битами с позиции 3 до 0 и получает значение 1100, а остальные биты — 0. Инициализатор набора битов bitvec6 передает строку и отправную точку, поэтому он инициализируется символами строки str, начиная с четвертого и до конца строки str. Остаток битов набора bitvec6 инициализируется нулями. Эти инициализации можно представить так:

Упражнения раздела 17.2.1

Упражнение 17.9. Объясните битовую схему, которую содержит каждый из следующих объектов bitset:

(a) bitset<64> bitvec(32);

(b) bitset<32> bv(1010101);

(c) string bstr; cin >> bstr; bitset<8> bv(bstr);

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК