Как вы уже наверное догадались, битовое поле — это просто массив битов фиксированного размера. Битовые поля удобно использовать для решения задач связанных с булевой логикой. Например, представление цветов или шифрование данных, ну или просто перевод чисел в двоичную систему исчисления, все это так или иначе связано с булевой логикой, а значит легко реализуемо с помощью битовых полей. В С++ для реализации булевой логики, раньше использовались побитовые операции &, |, ~ и тип данных int, но это было неэффективно, по нескольким причинам: неоправданный расход памяти для хранения одного бита и конечно же не всегда удобно использовать поразрядные логические операции.
Итак, чтобы воспользоваться классом bitset, достаточно подключить заголовочный файл <bitset>:
#include <bitset>
Класс bitset это шаблон, который принимает один параметр — размер поля в битах. Отсюда следует запомнить, что любой объект типа bitset всегда имеет фиксированную длину. Вот пример:
bitset<8> number(34);
В этом примере объявлено битовое поле — number размером 8 бит, которое инициализировано значением 34. Давайте рассмотрим полноценный пример в котором показываются преимущества класса bitset при вводе/выводе битовых полей.
#include <iostream>
#include <bitset> // заголовочный файл битовых полей
#include <iomanip> // для манипулятора setw()
using namespace std;
int main()
{
bitset<8> number;
cout << "Двоичное представление некоторых чисел:\n";
for( int i = 0; i < 21; i++) {
number = i;
cout << setw(2) << number.to_ulong() << " = " << number << endl;
}
return 0;
}
Сразу смотрим результат работы программы:
Двоичное представление некоторых чисел: 0 = 00000000 1 = 00000001 2 = 00000010 3 = 00000011 4 = 00000100 5 = 00000101 6 = 00000110 7 = 00000111 8 = 00001000 9 = 00001001 10 = 00001010 11 = 00001011 12 = 00001100 13 = 00001101 14 = 00001110 15 = 00001111 16 = 00010000 17 = 00010001 18 = 00010010 19 = 00010011 20 = 00010100
В строке 2, мы как всегда подключаем заголовочный файл bitset, для работы с битовыми полями. В восьмой строке, мы объявили битовое поле, размером 8 бит или — один байт. Далее в цикле мы выводим на экран двоичное представление чисел, начиная с 0 и заканчивая числом 20. Обратите внимание, что для вывода в двоичном формате никаких методов вызывать не надо, так как числа в битовых полях при инициализации сразу переводятся в двоичный формат. Также стоит обратить внимание на метод to_ulong(), он переводит двоичное представление числа в десятичное. Это хорошо видно в выводе результата программы.
Вот еще один пример программы, демонстрирующий некоторые операции класса bitset:
#include <iostream>
#include <bitset> // заголовочный файл битовых полей
using namespace std;
int main()
{
int number;
cout << "Введите целое число от 1 до 255: ";
cin >> number;
bitset<8> message(number);
cout << number << " = " << message << endl;
bitset<8> bit2 = message;
message = message.flip(); // поменять все биты на противоположные
cout << "Инвертированное число: " << message << endl;
bitset<8> bit3 = bit2 | message;
cout << bit2 << " | " << message << " = " << bit3 << endl; // операция логического ИЛИ
bitset<8> bit4 = bit3 & message;
cout << bit3 << " & " << message << " = " << bit4 << endl; // операция логического И
bitset<8> bit5 = bit3 ^ message;
cout << bit3 << " ^ " << message << " = " << bit5 << endl; // операция исключающего ИЛИ
return 0;
}
Из нового функционала стоит отметить метод flip(), он инвертирует все биты поля на противоположные, строка 15. Так же в программе показаны пример использования логических операций | & ^, смотреть строки 19, 22, 25. Результат программы показан ниже:
Введите целое число от 1 до 255: 12 12 = 00001100 Инвертированное число: 11110011 00001100 | 11110011 = 11111111 11111111 & 11110011 = 11110011 11111111 ^ 11110011 = 00001100