Класс bitset: набор битов фиксированного размера

Класс bitset реализует набор логических значений — например, флагов. Одно значение занимает один бит. В отличие от спецификации vector<bool>, набор имеет фиксированный размер, указываемый при объявлении объекта. Прежде чем использовать класс, необходимо в начало программы добавить инструкцию:

#include <bitset>

Создание объекта

Объявление класса bitset:

template<size_t N> class bitset;

Создать объект можно следующими способами (полный список конструкторов смотрите в документации):

  • объявить переменную без инициализации. Для этого перед названием переменной указывается название класса, а после названия внутри угловых скобок задается количество битов. Все биты автоматически получат значение 0. Пример объявления без инициализации:
std::bitset<8> arr;
std::cout << arr << std::endl; // 00000000
  • указать внутри круглых скобок целое число без знака:
std::bitset<8> arr(0xFF);
std::cout << arr << std::endl; // 11111111
  • указать внутри круглых скобок C-строку, состоящую из значений 0 и 1. Прототип конструктора:
template<typename CharT>
   explicit bitset(const CharT *str,
      typename std::basic_string<CharT>::size_type n
      = std::basic_string<CharT>::npos,
      CharT zero = CharT('0'), CharT one = CharT('1'));

Пример:

std::bitset<8> arr("11010101");
std::cout << arr << std::endl; // 11010101
  • указать внутри круглых скобок объект класса basic_string, после которого можно задать значения параметрам. Прототипы конструктора:
template<class CharT, class Traits, class Alloc>
   explicit bitset(const basic_string<CharT, Traits, Alloc> &str,
                   size_t pos=0);
template<class CharT, class Traits, class Alloc>
   bitset(const basic_string<CharT, Traits, Alloc> &str,
          size_t pos, size_t n);
template<class CharT, class Traits, class Alloc>
   bitset(const basic_string<CharT, Traits, Alloc> &str,
          size_t pos, size_t n,
          CharT zero, CharT one = CharT('1'));

Пример:

std::string str("11010101");
std::bitset<8> arr(str, 0, 8, '0', '1');
std::cout << arr << std::endl; // 11010101

Выполнение операций

Для вывода значения в окно консоли предназначен оператор <<, а для ввода значения с консоли — оператор >>:

std::bitset<8> arr;
std::cout << "arr = ";
std::cout.flush();
std::cin >> arr;                  // Получаем значение
if (std::cin.good())
   std::cout << arr << std::endl; // Выводим значение
else
   std::cout << "Error" << std::endl;

Один объект класса bitset можно присвоить другому объекту (создается копия):

std::bitset<8> arr1("11010101"), arr2;
arr2 = arr1;
std::cout << arr2 << std::endl; // 11010101

Над двумя объектами класса bitset определены операции сравнения == и !=, а также побитовые операции &, | и ^:

std::bitset<8> arr1(0b1100100), arr2(0b1001011), arr3;
arr3 = arr1 & arr2;
std::cout << arr3 << std::endl; // 01000000
arr3 = arr1 | arr2;
std::cout << arr3 << std::endl; // 01101111

С помощью оператора ~ можно заменить значение каждого бита противоположным:

std::bitset<8> arr1("01100100"), arr2;
arr2 = ~arr1;
std::cout << arr2 << std::endl; // 10011011

Для поразрядного сдвига предназначены операторы << и >>:

std::bitset<8> arr1("01100100"), arr2;
arr2 = arr1 >> 1;
std::cout << arr2 << std::endl; // 00110010
arr2 = arr1 << 1;
std::cout << arr2 << std::endl; // 11001000

Доступны также побитовые операторы с присваиванием: &=, |=, ^=, <<= и >>=.

Получение и изменение значений

К любому элементу набора можно обратиться как к элементу массива. Достаточно указать его индекс в квадратных скобках. Нумерация начинается с нуля. Можно как получить значение, так и изменить его. Если индекс выходит за границы диапазона, то возвращаемое значение не определено. Прототипы «операторного» метода:

bool operator[](size_t pos) const;
reference operator[](size_t pos);

Возвращаемая оператором [] ссылка, описывается с помощью класса reference. Этот класс содержит следующие методы:

operator bool() const noexcept;
reference &operator=(bool x) noexcept;
reference &operator=(const reference &x) noexcept;
reference &flip() noexcept;
bool operator~() const noexcept;

Пример использования оператора []:

std::bitset<8> arr;
std::cout << arr[0] << std::endl; // 0
arr[0] = true;
std::cout << arr << std::endl;    // 00000001
arr[1] = arr[0];
std::cout << arr << std::endl;    // 00000011
arr[0].flip();
std::cout << arr << std::endl;    // 00000010
arr[0] = ~arr[2];
std::cout << arr << std::endl;    // 00000011

Для получения и изменения значений предназначены следующие методы:

  • set() — устанавливает или сбрасывает флаги. Если указанный индекс выходит за границы диапазона, то генерируется исключение. Прототипы метода:
bitset<N> &set(size_t pos, bool val=true);
bitset<N> &set() noexcept;

Первый прототип изменяет значение одного флага, расположенного по индексу pos, а второй — устанавливает все флаги:

std::bitset<8> arr1, arr2;
arr1.set(0, true);
std::cout << arr1 << std::endl; // 00000001
arr2.set();
std::cout << arr2 << std::endl; // 11111111
  • flip() — инвертирует значение одного или всех флагов. Если указанный индекс выходит за границы диапазона, то генерируется исключение. Прототипы метода:
bitset<N> &flip(size_t pos);
bitset<N> &flip() noexcept;

Первый прототип инвертирует значение одного флага, расположенного по индексу pos, а второй — инвертирует значения всех флагов:

std::bitset<8> arr1, arr2;
arr1.flip(0);
std::cout << arr1 << std::endl; // 00000001
arr2.flip();
std::cout << arr2 << std::endl; // 11111111
  • reset() — сбрасывает один или все флаги. Если указанный индекс выходит за границы диапазона, то генерируется исключение. Прототипы метода:
bitset<N> &reset(size_t pos);
bitset<N> &reset() noexcept;

Первый прототип сбрасывает один флаг, расположенный по индексу pos, а второй — сбрасывает все флаги:

std::bitset<8> arr1("11111111"), arr2("11111111");
arr1.reset(0);
std::cout << arr1 << std::endl; // 11111110
arr2.reset();
std::cout << arr2 << std::endl; // 00000000
  • test() — возвращает значение true, если флаг, расположенный по индексу pos, установлен, и false — в противном случае. Если индекс выходит за границы диапазона, то генерируется исключение. Прототип метода:
bool test(size_t pos) const;

Пример:

std::bitset<8> arr("01100101");
std::cout << arr.test(0) << std::endl; // 1
std::cout << arr.test(1) << std::endl; // 0
  • any() — возвращает значение true, если установлен хотя бы один флаг в наборе, и false — в противном случае. Прототип метода:
bool any() const noexcept;

Пример:

std::bitset<8> arr1("00000100"), arr2;
std::cout << arr1.any() << std::endl; // 1
std::cout << arr2.any() << std::endl; // 0
  • all() — возвращает значение true, если установлены все флаги, и false — в противном случае. Прототип метода:
bool all() const noexcept;

Пример:

std::bitset<8> arr1("11111111"), arr2("11111110");
std::cout << arr1.all() << std::endl; // 1
std::cout << arr2.all() << std::endl; // 0
  • none() — возвращает значение true, если ни один флаг в наборе не установлен, и false — в противном случае. Прототип метода:
bool none() const noexcept;

Пример:

std::bitset<8> arr1("11111111"), arr2;
std::cout << arr1.none() << std::endl; // 0
std::cout << arr2.none() << std::endl; // 1
  • count() — возвращает количество установленных флагов. Прототип метода:
size_t count() const noexcept;

Пример:

std::bitset<8> arr1("11010111"), arr2;
std::cout << arr1.count() << std::endl; // 6
std::cout << arr2.count() << std::endl; // 0
std::cout << arr1.size() << std::endl;  // 8
  • size() — возвращает общее количество флагов. Прототип метода:
constexpr size_t size() const noexcept;

Преобразование набора битов в число или строку

Преобразовать набор битов в целое число без знака позволяют методы to_ulong() и to_ullong(). Если размер набора больше размера типа, то генерируется исключение overflow_error. Прототипы методов:

unsigned long to_ulong() const;
unsigned long long to_ullong() const;

Пример:

std::bitset<8> arr(0xFF);
unsigned long x = arr.to_ulong();
std::cout << x << std::endl;                      // 255
unsigned long long y = arr.to_ullong();
std::cout << y << std::endl;                      // 255

Для преобразования набора битов в строку предназначен метод to_string(). Основные прототипы метода (полный список смотрите в документации):

basic_string<char, char_traits<char>, allocator<char> >
   to_string() const;
basic_string<char, char_traits<char>, allocator<char> >
   to_string(char zero, char one='1') const;
template<class CharT>
   basic_string<CharT, char_traits<CharT>, allocator<CharT> >
   to_string() const;
template<class CharT>
   basic_string<CharT, char_traits<CharT>, allocator<CharT> >
   to_string(CharT zero, CharT one=CharT('1')) const;

Пример:

std::bitset<8> arr(0xFF);
std::string str = arr.to_string();
std::cout << str << std::endl;                    // 11111111
std::wstring wstr = arr.to_string<wchar_t>();
std::wcout << wstr << std::endl;                  // 11111111

Учебник C++ (Qt Creator и MinGW)
Учебник C++ (Qt Creator и MinGW) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов