Программирование >>  Инициализация объектов класса, структура 

1 ... 51 52 53 [ 54 ] 55 56 57 ... 395


enum students { Danny = 1, Jeffrey, Ethan, Zev, Ebie, ...

AnnaP = 26, AnnaL = 27 }; const int student size = 27;

наш битов вектор начинается с 1 boo1 has passed iz[ student size+l ] ; for ( int index = 1; index <= student size; ++-index )

Вот пример использования:

has passed quiz[ index ] = bit on( quiz1, index );

Раз уж мы начали инкапсулировать действия с битовым вектором в функции, следующим шагом нужно создать класс. Стандартная библиотека С++ включает такой класс bitset, его использование описано ниже.

1 << 27;

Применив побитовую операцию ИЛИ к переменной quiz1 и нашей константе, получим нужный результат: значение 27-й бита станет равным значение 1, а другие бит1 останутся неизменными.

quiz1 = 1<<27;

Теперь представим себе, что преподаватель перепроверил результаты теста и выяснил, что студент 27 зачет не сдал. Теперь нужно присвоить нуль 27-му биту, не трогая остальных. Сначала применим побитовое НЕ к предыдущей константе и получим число, в котором все биты, кроме 27-го, равны 1:

~(1<<27 );

Теперь побитово умножим (И) эту константу на quiz1 и получим нужный результат: 0 в 27-м бите и неизменные значения остальных.

quiz1 &= ~(1<<27);

Как проверить значение того же 27-го бита? Побитовое И дает true, если 27-й бит равен 1, и false, если 0:

bool hasPassed = iz1 & (1 27);

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

inline boo1 bit on (unsigned int ui, int pos) return u1 & ( 1 << pos ); или встроенные функции:



Упражнение 4.12 Даны два целых числа:

unsigned int ui1 = 3, ui2

Каков результат следующих выражений?

(a) ui1 s ui2 (c) uil ui2

(b) ui1 ss ui2 (d) uil ui2 Упражнение 4.13

Используя пример функции bit on() , создайте функции bit turn on() (выставляет бит в 1), bit turn off() (сбрасывает бит в 0), flip bit() (меняет значение на противоположное) и bit off() (возвращает true, если бит равен 0). Напишите программу, использующую ваши функции.

Упражнение 4.14

В чем недостаток функций из предыдущего упражнения, использующих тип unsigned int? Их реализацию можно улучшить, используя определение типа с помощью typedef или механизм функций-шаблонов. Перепишите функцию bit on() ,применив сначала typedef, а затем механизм шаблонов.

4.12. Класс bitset

Таблица 4.4. Операции с классом bitset

Операция

Значение

Использование

test(pos)

Бит pos равен 1?

a.test(4)

any()

Хотя бы один бит равен 1?

a.any()

none()

Ни один бит не равен 1?

a. none()

count()

Количество битов, равных 1

a. count()

size()

Общее количество битов

a. size()

[pos]

Доступ к биту pos

a[4]

flip()

Изменить значения всех

a.flip()

flip(pos)

Изменить значение бита pos

a.flip(4)

set()

Выставить все биты в 1

a.set()

set(pos)

Выставить бит pos в 1

a.set(4)

reset()

Выставить все биты в 0

a.reset()

reset(pos)

Выставить бит pos в 0

a.reset(4)

Как мы уже говорили, необходимость создавать сложные выражения для манипуляции битовыми векторами затрудняет использование встроенных типов данных. Класс bitset упрощает работу с битовым вектором. Вот какое выражение нам приходилось писать в предыдущем разделе для того, чтобы взвести 27-й бит:



for ( int index=0; index<32; ++index ) if ( index % 2 == 0 )

каждый четный бит:

bitvec[ index ] = 1;

Аналогично существует два способа проверки значений каждого бита - с помощью функции test() и с помощью индекса. Функция () возвращает true, если

if ( bitvec.test( 0 ))

соответствующий бит равен 1, и false в противном случае. Например:

присваивание bitvec[0]=1 сработало!;

quiz1 = 1<<27;

При использовании bitset то же самое мы можем сделать двумя способами:

quiz1[27] = 1; или

quiz1.set(27);

(В нашем примере мы не используем нулевой бит, чтобы сохранить естественную нумерацию. На самом деле, нумерация битов начинается с 0.)

Для использования класса bitset необходимо включить заголовочный файл:

#include <bitset>

Объект типа bitset может быть объявлен тремя способами. В определении по умолчанию мы просто указываем размер битового вектора:

bitset<32> bitvec;

Это определение задает объект bitset, содержащий 32 бита с номерами от 0 до 31. Все биты инициализируются нулем. С помощью функции any() можно проверить, есть ли в векторе единичные биты. Эта функция возвращает true, если хотя бы один бит отличен от нуля. Например:

bool is set = bitvec.any();

Переменная is set получит значение false, так как объект bitset по умолчанию инициализируется нулями. Парная функция none() возвращает true, если все биты равны нулю:

bool is not set = bitvec.none();

Изменить значение отдельного бита можно двумя способами: воспользовавшись функциями set() и reset() или индексом. Так, следующий цикл выставляет в 1



1 ... 51 52 53 [ 54 ] 55 56 57 ... 395

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