Битовые поля в С++

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

Сразу смотрим результат работы программы:

CppStudio.com
Двоичное представление некоторых чисел: 
 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. Результат программы показан ниже:

CppStudio.com
Введите целое число от 1 до 255: 12 
12 = 00001100 
Инвертированное число: 11110011 
00001100 | 11110011 = 11111111 
11111111 & 11110011 = 11110011 
11111111 ^ 11110011 = 00001100
Автор: Marienko L.
Дата: 16.01.2014
Поделиться:

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.