Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lekcija-18.pdf
Скачиваний:
17
Добавлен:
27.03.2016
Размер:
285.74 Кб
Скачать

Битовые поля структур и объединений

Определение битовых полей

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

Общий синтаксис описания битового поля: тип_поля [имя_поля]: ширина_поля;

Члены битовых полей могут иметь значения базовых целых типов (знаковых или беззнаковых). Эти ключевые слова записываются в поле «тип_поля». Для переносимости программ лучше указывать служебные слова signed или unsigned, однако заметим, что сама природа структур с битовыми полями не способствует переносимости.

Определение структурной переменной с битовыми полями имеет формат: struct имя_структурного _типа {

тип_поля1 имя_поля1: ширина_поля1; тип_поля2 имя_поля2: ширина_поля2;

} имя_структурной_переменной;

Каждому полю выделяется столько бит, сколько задается в поле «ширина». Ссылка на битовое поле выполняется по имени, указываемому в поле «имя». Например:

struct EXAMPLE {int i:3; unsigned j:2; int :3;

int k: 2;

} my_struct;

Это описание включает 4 битовых поля: i из трех битов (значения от -4 до 3), j из двух битов (значения от 0 до 3), поле без имени из трех битов и поле k из двух битов (значения от -2 до 1). В памяти, отводимой под структуру EXAMPLE, битовое поле k будет расположено не непосредственно за полем j, а через три бита от него (на величину безымянного поля). Неименованное поле используется в структуре как заполнение: ничто не будет храниться в этих битах.

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

переменной поразрядной логической операцией с предыдущим содержимым поля.

Структуры с битовыми полями используются подобно обычным структурам.

Битовые поля не могут быть самостоятельным объектом программы, а лишь элементами структур, объединений, классов. Не могут они объединяться и в массивы. К битовым полям не может быть применен оператор взятия адреса &, так

как битовое поле может находиться внутри байта.

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

19

Битовые поля позволяют рационально использовать память с помощью хранения данных в минимально требуемом количестве битов, экономить память, работая с однобитовыми флажками, формировать объекты с длиной внутреннего представления, не кратной байту (т.е. упаковывать информацию). Их назначение – удобный доступ к отдельным битам, компактное представление в памяти упакованных структур. Однако в ряде случаев их использование может привести к замедлению выполнения программы.

Компилятор старается размещать битовые поля в памяти последовательно. Для

выравнивания он может свободно переходить к следующему байту или слову.

Манипуляции с битовыми полями являются машинно-зависимыми. Поля могут размещаться как слева направо, так и справа налево (зависит от реализации). В некоторых компьютерах битовые поля могут пересекать границы машинного слова, тогда как в других – нет, но максимальная ширина поля не должна превышать длины слова компьютера. Размещение поля с длиной, не кратной длине слова или байта, возможно с расположением «встык», без пропусков или же с выравниванием на границе. Влиять на размещение битовых полей можно и на уровне синтаксиса языка С++ (в этом случае для выравнивания можно использовать недоступные биты – безымянные поля).

Для структуры с битовыми полями: struct

{int a:10;

int b:14;

} xx;

представление в памяти переменной хх, в зависимости от реализации может иметь

вид:

при выравнивании на границе слова или байта:

7

0

7

0

7

0

7

0

 

z z z z z z

 

z z z z z z z z

 

ww

 

wwwwwwww

 

 

хх

.b (14 битов)

 

 

 

хх.a (10 битов)

при плотной упаковке:

 

 

 

 

 

 

7

0

7

0

7

0

7

0

 

 

 

z z z z z z z z

z z z z z z ww

 

wwwwwwww

 

 

 

 

хх.b (14 битов)

хх.a (10 битов)

Примеры использования битовых полей Вывод значений битовых полей

Объяснить результат!!!

если дана структура с битовыми полями EXAMPLE: struct EXAMPLE { int i:2;

unsigned j:2; int :2;

int k: 2;

};

int main()

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

20

-2 2 1

{

EXAMPLE my_struct;

my_struct.i=3; my_struct.j=3; my_struct.k=-1;

cout << dec << my_struct.i <<" " << my_struct.j <<" "<<my_struct.k << endl;

-1 3 -1

my_struct.i = 2; my_struct.j = 2; my_struct.k = 1;

cout << dec << my_struct.i << " "<< my_struct.j << " " <<my_struct.k << endl; _getch();

return 0;

}

Формирование кода символа с помощью битовых полей объединения

Формирование кода символа ‘D’ (6810=4416).

Вариант 1:

union

{char simb;

struct {int x:5;

 

 

 

} hh;

 

int y:3;

}cod;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

int main()

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

cod.hh.x=4;

 

 

 

 

 

 

 

cod.hh.y=2;

 

 

 

 

 

// D (код 44)

cout<<cod.simb;

 

 

 

 

_getch();

 

 

 

 

 

 

 

 

 

return 0;

 

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

7

 

 

 

 

 

 

 

 

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

1

 

0

0

0

1

 

0

0

 

 

hh.y (3 бита)

hh.x

(5 битов)

 

 

 

 

 

 

 

Формирование кода символа ‘D’ (6810=4416).

Вариант 2.

Используется функция, которая упаковывает в байт остатки от деления на 16 двух чисел

int main()

{

int a=36, b=20; //два числа для формирования кода символа ‘D’ cout << cod(a, b) << endl;

_getch(); return 0;

}

unsigned char cod (int a, int b) { union {

unsigned char z;

struct {unsigned int x:4;

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

21

" << cod.byte.a6 ; //так как все биты " << cod.byte.a4 ; //имеют названия " << cod.byte.a2 ;
" << cod.byte.a0 ;
//определение локальный переменной-объединения
//занесение в объединение значения аргумента функции
7 6 5 4 3 2 1 0\n";
//каждый бит получает название

} hh;

unsigned int y:4;

 

} un;

//остаток равен 4

un.hh.x=a%16 ;

un.hh.y=b%16 ;

//остаток равен 4

return un.z ;

//возвращает символ с кодом 44

}

Формирование байта и вывод на экран его двоичного представления

(функция cod() упаковывает в байт два числа

функция binary() выводит на экран двоичное представление байта-параметра):

unsigned char cod (int a, int b); void binary (unsigned char ch); int main()

{int k, m, n ;

cout << "m= ? n=? : "; cin >> m >> n;

k = cod (m, n);

 

 

//упаковка значений в байт

cout << "cod= " << hex <<k <<endl;

//вывод кода

cout << "simvol=

" << char(k) << endl; //вывод символа

cout << dec << endl;

//вывод на экран двоичного представления байта

binary(k) ;

 

_getch();

 

 

 

return 0;

 

 

 

}

 

 

 

unsigned char cod (int a, int b)

 

{union {

 

 

 

unsigned char z;

 

 

struct {unsigned int x:4;

 

} hh;

unsigned int y:4;

 

 

 

 

} un;

//получение остатков от чисел-аргументов

un.hh.x=a%16 ;

un.hh.y=b%16 ;

 

 

 

}return un.z ;

//возвращает символ с полученным кодом 44

void binary (unsigned char ch)

//вывод на экран двоичного представления байта

{ union {

 

//определение локального объединяющего типа

unsigned char ss; struct {

unsigned a0:1; unsigned a1:1; unsigned a2:1; unsigned a3:1; unsigned a4:1; unsigned a5:1; unsigned a6:1;

} byte; unsigned a7:1;

} cod;

cod.ss=ch;

cout << "nomera bitov: cout <<"znachenie: ";

cout << " " << cod.byte.a7 << " cout << " " << cod.byte.a5 << " cout << " " << cod.byte.a3 << " cout << " " << cod.byte.a1 << "

}cout <<endl;

Программирование – лекция 18 (лекции Стрикелевой Л.В.)

22

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]