Как вы уже наверное догадались, битовое поле — это просто массив битов фиксированного размера. Битовые поля удобно использовать для решения задач связанных с булевой логикой. Например, представление цветов или шифрование данных, ну или просто перевод чисел в двоичную систему исчисления, все это так или иначе связано с булевой логикой, а значит легко реализуемо с помощью битовых полей. В С++ для реализации булевой логики, раньше использовались побитовые операции &
, |
, ~
и тип данных 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