Программирование >>  Разработка устойчивых систем 

1 ... 121 122 123 [ 124 ] 125 126 127 ... 196


ные 16 случайных битов влево вплоть до заполнения битового поля (параметризованного по длине). Сгенерированное число и очередные 16 бит объединяются оператором =.

Функция main О сначала демонстрирует дискретный характер выделения памяти для битовых полей. Если поле содержит менее 32 бит, то sizeof возвращает 4 (4 байт = 32 бит), размер типа long в большинстве реализаций. Если поле содержит от 32 до 64 бит, для их хранения требуются два числа типа long, если больше 64 - 3 числа, и так далее. Следовательно, наиболее эффективное использование памяти достигается в том случае, если количество битов кратно размеру long. С другой стороны, битовые поля не требуют лишних затрат на хранение служебной информации - все выглядит так, словно вы вручную реализовали работу с набором битов через массив long.

Несмотря на отсутствие других преобразований из bitset, помимо to ulong(), имеется потоковый итератор вывода, который выдает строку из единиц и нулей. Длина строки может достигать длины битового поля.

Примитивы для задания двоичных значений по-прежнему отсутствуют, но зато bitset поддерживает почти такой же удобный формат - объекты string из единиц и нулей, в которых младший (наименее значимый) бит расположен справа. Три конструктора, продемонстрированных выше, получают соответственно всю строку, подстроку, начинающуюся со второго символа, и подстроку из символов 2-11. Содержимое bitset можно вывести в ostream оператором , и вы получите желаемое двоичное представление из О и 1. Также возможно чтение двоичных данных из istream оператором (не показано).

Битовые поля поддерживают всего три внешних оператора: конъюнкции (&), дизъюнкции (I) и исключающей дизъюнкции (). Каждый из этих операторов создает новое битовое поле для своего возвращаемого значения. Все операторы класса работают в более эффективных формах &=, = и т. д., не создающих временные объекты. С другой стороны, эти формы изменяют значение bitset (объект а в большинстве тестов данного примера). Чтобы предотвратить нежелательную модификацию объекта, мы создаем временный левосторонний объект, конструируя копию а; этим объясняется присутствие формы BS(a). Программа выводит результаты каждого теста и периодически повторяет вывод а, чтобы вам было удобнее изучать результаты.

В остальном пример не требует комментариев. Если что-то останется непонятным, обращайтесь за подробностями к описанию компилятора или другой документации, упоминавшейся ранее.

Контейнер vector<bool>

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

Битовые операции vector<bool> существенно ограничены по сравнению с bitset. К основным операциям вектора добавляется единственная функция flip(), инвер-



тирующая все биты. В отличие от bitset, контейнер vector<bool> не поддерживает функции установки-сброса отдельных битов set() и reset(). Оператор индексирования [ ] возвращает объект типа vector<bool>::reference, который также поддерживает функцию Шр(), для инвертирования этого отдельного бита.

: C07:VectorOfBool.срр Специализация vector<bool> #include <bitset> linclude <cstddef> linclude <iostream> linclude <iterator> linclude <sstream> linclude <vector> using namespace std:

int mainO { vector<bool> vbClO. true): vector<bool>::iterator it: forCit = vb.beginO; it != vb.endO: it++)

cout *it: cout endl; vb.push back(false); ostream iterator<bool> outCcout. ); copyCvb.beginO. vb.endO. out); cout endl:

bool ab[] - { true, false, false, true, true.

true. true, false, false, true }: Существует похожий конструктор: vb.assignCab. ab + sizeof(ab)/sizeofCbool)); copyCvb.beginO. vb.endO. out): cout endl;

vb.flipO; Инвертирование всех битов copyCvb.beginO, vb.endO, out); cout endl:

for(size t i = 0: i < vb.sizeC): i++) vb[i] = 0: Сэквивалент false ) vb[4i - true: vb[5] = 1:

vb[7].flipC); Инвертирование одного бита copyCvb.beginO. vb.endO, out); cout endl;

Преобразование в bitset: ostringstream os: copyCvb.beginO. vb.endO.

ostream iterator<bool>(os. )); bitset<10> bsCos.strO): cout Bitset:\n bs endl; } III:-

Последний фрагмент этого примера преобразует vector<bool> в bitset через промежуточную строку из единиц и нулей. Чтобы такое преобразование стало возможно, размер bitset должен быть известен на стадии компиляции, поэтому такое преобразование на практике применяется относительно редко.

Специализация vector<bool> в определенном смысле является неполноценным контейнером STL - она не дает некоторых гарантий, предоставляемых другими контейнерами. Например, для других контейнеров выполняются следующие отнощения:



Ассоциативные контейнеры

Множество (set), отображение (тар), мультимножество (multiset) и мультиотоб-ражение (multimap) относятся к категории ассоциативных контейнеров, потому что их элементы представляют собой ассоциированные пары ключ-значение . Точнее говоря, ключи ассоциируются со значениями в отображениях и мультиотобра-жениях, однако множество можно рассматривать как отображение, содержащее только ключи без значений (его даже можно реализовать подобным образом). Сказанное относится и к связи между мультимножествами и мультиотображениями. Из-за этого структурного сходства множества и мультимножества также причислены к категории ассоциативных контейнеров.

Важнейшие операции с ассоциативными контейнерами - занесение новых элементов, а для множеств - проверка наличия элементов в контейнере. При работе с отображением нужно сначала проверить, присутствует ли ключ в контейнере, и если присутствует, получить значение, ассоциированное с этим ключом. Впрочем, это лишь фундаментальный принцип. Основные операции с ассоциативными контейнерами продемонстрированы в следующем примере:

: C07:AssociativeBasics.cpp {-Ьог}

Основные операции с множествами и отображениями

#include <cstddef>

linclude <iostream>

linclude <iterator>

linclude <map>

linclude <set>

linclude Noisy.h

using namespace std;

int mainO { Noisy na[7];

Добавление элементов в конструкторе ;

set<Noisy> ns(na, па + sizeof na/sizeof(Noisy));

Обычная вставка:

Noisy n;

ns.insert(n):

cout endl;

Проверка наличия элемента;

cout ns.count(n)= ns.count(n) endl;

if(ns.find(n) != ns.endO)

cout n( n ) found in ns endl; Вывод элементов;

Если с - контейнер STL. отличный от vector<boo1>: Т& г = c.frontO: Т* р = &*c.begin():

Для всех остальных контейнеров функция front() возвращает левосторонний объект (нечто, для чего можно получить неконстантную ссылку), а функция begin() возвращает объект, который можно разыменовать, а потом получить его адрес. Для vector<bool> и то, и другое невозможно, потому что отдельные биты адресоваться не могут. Оба контейнера (vector<bool> и bitset) используют промежуточный класс (вложенный класс reference, упоминавшийся ранее) для чтения и записи отдельных битов.



1 ... 121 122 123 [ 124 ] 125 126 127 ... 196

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика