Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

Для примера рассмотрим, как извлечь (низкоуровневую) информацию из целого числа (возможно, из-за того, что мы хотим передать его как набор байтов через двоичный механизм ввода-вывода).

void f(short val) // пусть число состоит из 16 битов, т.е. 2 байта

{

unsigned char left = val>>8; // крайний левый

// (самый старший) байт

unsigned char right = val&0xff; // крайний правый

// (самый младший) байт

// ...

bool negative = val&0x8000; // знаковый бит

// ...

}

Такие операции не редкость. Они известны как “сдвиг и наложение маски” (“shift and mask”). Мы выполняем сдвиг (“shift”), используя операторы

<<
или
>>
, чтобы переместить требуемые биты вправо (в младшую часть слова), где ними легко манипулировать. Мы накладываем маску (“mask”), используя оператор “и” (
&
) вместе с битовой комбинацией (в данном случае
0xff
), чтобы исключить (установить равными нулю) биты, нежелательные в результате.

При необходимости именовать биты часто используются перечисления. Рассмотрим пример.

enum Printer_flags {

acknowledge=1,

paper_empty=1<<1,

busy=1<<2,

out_of_black=1<<3,

out_of_color=1<<4,

// ...

};

Этот код определяет перечисление, в котором каждый элемент равен именно тому значению, которому соответствует его имя.

Такие значения полезны, потому что они комбинируются совершенно независимо друг от друга.

unsigned char x = out_of_color | out_of_black; // x = 24 (16+8)

x |= paper_empty; // x = 26 (24+2)

Отметим, что оператор

|=
можно прочитать как “установить бит” (или “установить некоторый бит”). Значит, оператор
&
можно прочитать как “установлен ли бит?” Рассмотрим пример.

if (x& out_of_color) { // установлен ли out_of_color? (Да, если

// установлен)

// ...

}

Оператор

&
по-прежнему можно использовать для наложения маски.

unsigned char y = x &(out_of_color | out_of_black); // y = 24

Теперь переменная

y
содержит копию битов из позиций 4 и 4 числа
x
(
out_of_color
и
out_of_black
).

Очень часть переменные типа

enum
используются как набор битов. При этом необходимо выполнить обратное преобразование, чтобы результат имел вид перечисления. Рассмотрим пример.

// необходимо приведение

Flags z = Printer_flags(out_of_color | out_of_black);

Приведение необходимо потому, что компилятор не может знать, что результат выражения

out_of_color | out_of_black
является корректным значением переменной типа
Flags
. Скептицизм компилятора обоснован: помимо всего прочего, ни один из элементов перечисления не имеет значения, равного 24 (
out_of_color | out_of_black
), но в данном случае мы знаем, что выполненное присваивание имеет смысл (а компилятор — нет).

25.5.5. Битовые поля

Как указывалось ранее, биты часто встречаются при программировании интерфейсов аппаратного обеспечения. Как правило, такие интерфейсы определяются как смесь битов и чисел, имеющих разные размеры. Эти биты и числа обычно имеют имена и стоят на заданных позициях в слове, которое часто называют регистром устройства (device register). В языке C++ есть специальные конструкции для работы с такими фиксированными схемами: битовые поля (bitfields). Рассмотрим номер страницы, используемый менеджером страниц глубоко внутри операционной системы. Вот как выглядит диаграмма, приведенная в руководстве по работе с операционной системой.

З2-битовое слово состоит из двух числовых полей (одно длиной 22 бита и другое — 3 бита) и четырех флагов (длиной один бит каждый). Размеры и позиции этих фрагментов фиксированы. Внутри слова существует даже неиспользуемое (и неименованное) поле. Эту схему можно описать с помощью следующей структуры:

struct PPN { // Номер физической страницы

// R6000 Number

unsigned int PFN:22; // Номер страничного блока

  • Читать дальше
  • 1
  • ...
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: