Класс-шаблон bitset и пример на него
В С++ есть удобный стандартный контейнер <bitset>
, предназначенный для хранения битовых цепочек и операций над отдельными битами, так что выполнять трудоёмкие преобразования побитовыми логическими операциями в современных компиляторах уже необязательно.
Сравним, насколько для <bitset>
проще выполняются действия с отдельными битами, описанные в этой заметке.
#include <iostream> #include <string> #include <bitset> #include <Windows.h> using namespace std; int main() { setlocale(LC_ALL, "Rus"); SetConsoleCP(1251); SetConsoleOutputCP(1251); bitset<8> set(string("00000000")); cout << endl << "Исходные биты: " << set.to_string() << ", размер=" << sizeof(set) << " байт"; set.flip(2); cout << endl << "Переключен бит 2: " << set.to_string(); cout << endl << "Проверка бита 2: " << set[2]; set.set(3, 1); cout << endl << "Включен бит 3: " << set.to_string(); set.set(3, 0); cout << endl << "Выключен бит 3: " << set.to_string(); cin.get(); return 0; }
Вывод этого примера (Visual Studio 2015):
Исходные биты: 00000000, размер=4 байт Переключен бит 2: 00000100 Проверка бита 2: 1 Включен бит 3: 00001100 Выключен бит 3: 00000100
Как видим, размер битсета, конечно, не 1 байт, а размер целого в текущей системе (это была 32-разрядка). Так что в реальных приложениях, особенно системных, старый добрый способ "прямого" доступа к битам никто не отменял.
Дока по bitset как на cplusplus.com, ссылки туда же
bitset
— это специальный класс-контейнер, который предназначен для хранения битовых значений (элементы этого контейнера могут иметь значения: 0 и/или 1, истина или ложь).
Класс bitset
очень похож на обычный массив, но, в отличии от массива, под каждый элемент объекта типа bitset
отводится всего один бит, то есть пространство в памяти, которое занимают битовые маски максимально оптимизировано. Что позволяет использовать память в восемь раз меньше, чем наименьший элементарный тип данных в C++ — char
).
Каждый элемент (каждый бит) может быть доступен по отдельности: например, у нас есть объект типа bitset
c именем mybitset
, необходимо получить доступ к четвертому биту. Для этого, после имени массива, в квадратных скобочках укажем индекс бита, как если бы мы хотели получить доступ к элементу массива — mybitset[3]
.
Иногда этот тип данных используют в качестве логических переменных, отдельные элементы в таком случае являются ссылками на логические значения.
class bitset::reference { friend class bitset; reference(); // закрытый конструктор public: ~reference(); operator bool () const; // преобразовать к типу bool reference& operator= ( bool x ); // присвоить значение типа bool reference& operator= ( const reference& x ); // присвоить битовое значение reference& flip(); // flip bit value bool operator~() const; // инвертировать значение }
Кроме перегрузки нескольких операторов и обеспечения прямого доступа к битам, объект bitsets
может быть преобразован в целочисленное беззнаковое значение и — в двоичную строку (подробно — см. конструктор, bitset:: to_ulong и bitset::to_string). Битовые сетки также могут напрямую вставляется и извлекается из потока в двоичном формате.
Битовые маски имеют фиксированный размер. В С++ есть подобный контейнер, который также оптимизирует выделяемое пространство и, при этом, позволяет динамически изменять размер массива, смотреть статью про контейнер vector
(vector <bool>
— битовая маска посредством класса-контейнера vector
).
В настоящей реализации класса-контейнера Стандартной библиотеки шаблонов C++, объект типа bitset
принимает один параметр шаблона:
template < size_t N > class bitset;
где, параметр шаблона имеет следующее значение:
N
— количество битов, которое содержит битовая маска (size_t
— целочисленный тип данных).
size_t
— псевдоним одного из беззнаковых целочисленных типов данных в С++.
Этот тип данных может представить размер любого объекта в байтах. size_t
возвращается оператором sizeof и широко используется в стандартной библиотеке для представления размеров и для подсчета.
Функции-члены класса-контейнера bitsets стандартной библиотеки шаблонов С++ | |
---|---|
constructor | Конструктор класса bitset . |
используемые операторы | Перегруженные операторы для выполнения побитовых логических операций и организации ввода/вывода объектов bitset . |
Доступ к битам | |
operator[] | Перегруженный оператор квадратных скобок, для организации непосредственного доступа к битам. |
Битовые операции | |
set | Функция позволяет инициализировать все биты единицами или изменить значение отдельного бита. |
reset | Обнуление указанных битов (сброс битов в 0). |
flip | Преобразовать битовую маску в обратный код. То есть 1-цы заменить нулями, а 0 — единицами. |
Операции с битовыми масками | |
to_ulong | Преобразовать битовый объект в целое длинное беззнаковое значение. |
to_string | Преобразовать битовую последовательность в строку типа string , которая будет содержать символы 0 и/или 1. |
count | Возвращает количество единичных битов объекта bitset . |
size | Вернуть размер объекта bitset (количество битов). |
test | Возвращает значение указанного бита объекта bitset . |
any | Проверяет битовое значение на предмет наличия в объекте bitset единичных битов. |
none | Проверяет битовое значение на предмет наличия в объекте bitset нулевых битов. |
16.11.2016, 21:30 [11299 просмотров]