БлогNot. Класс-шаблон bitset и пример на него

Класс-шаблон 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 [10724 просмотра]


теги: c++ памятка числа

К этой статье пока нет комментариев, Ваш будет первым