|
Программирование >> Разработка устойчивых систем
ные 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, упоминавшийся ранее) для чтения и записи отдельных битов.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |