Битовые поля
Размещение битовых полей в памяти
От реализации зависит порядок размещения в памяти полей одной структуры. Поля могут размещаться как слева направо, так и справа налево. Любой код программ, использующий битовые поля, зависит от компьютера и компилятора.
Пример 2.
#include "stdafx.h" #include <iostream> using namespace std; struct expl { int i:2; unsigned j:2; int :2; int k:2; int dummy: 8; } my; int _tmain(int argc, _TCHAR* argv[]) { my.dummy = 0; my.i = 1; my.j = 3; my.k = -1; printf("%d\n", my); printf("Поля: %d\t%d\t%d", my.i, my.j, my.k); system("pause"); return 0; }
На рис. 18.1 показывается, как выглядит переменная структурного типа my в памяти.
Пример 3. Иллюстрация возможностей объединений и структур с битовыми полями.
В программе вводятся значения двух целых переменных m и n, и остатки от их деления на 16 заносятся соответственно в четыре младших и в четыре старших разряда одного байта. Таким образом, выполняется некоторая кодировка введенных значений переменных m и n. Затем печатается изображение содержимого сформированного байта.
Обратите внимание на использование объединения. В функции cod() запись данных производиться в элементы (битовые поля) структуры hh, входящей в объединение un, а результат выбирается из того же объединения un в виде одного байта. В функции binary() происходит обратное преобразование – в нее как значение параметра передается байт, содержимое которого побитово "расшифровывается" за счет обращения к отдельным полям структуры byte, входящей в объединение cod.
//Структуры, объединения и битовые поля #include "stdafx.h" #include <iostream> using namespace std; void binar (unsigned char); //прототип функции unsigned char cod (int, int); // прототип функции int _tmain(int argc, _TCHAR* argv[]) { unsigned char k; int m, n; printf("m="); scanf("%d", &m); printf("n="); scanf("%d", &n); k=cod(m,n); printf("cod=%u\n", k); binar(k); system("pause"); return 0; } /*Упаковка в один байт остатков от деления на 16 двух целых чисел*/ unsigned char cod (int a, int b) { union { unsigned char z; struct { unsigned int x : 4;//младшие биты unsigned int y : 4;//старшие биты } hh; } un; un.hh.x=a%16; un.hh.y=b%16; return un.z; } //двоичное представление байта void binar (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; unsigned a7 : 1; } byte; } cod; cod.ss=ch; printf("Номер битов: 7 6 5 4 3 2 1 0\n"); printf("Значение битов: %d %d %d %d %d %d %d %d\n", cod.byte.a7, cod.byte.a6, cod.byte.a5, cod.byte.a4, cod.byte.a3, cod.byte.a2, cod.byte.a1, cod.byte.a0); }
Результат выполнения программы:
Первый вариант
m=1 n=3 cod=49 Номер битов: 7 6 5 4 3 2 1 0 Значение битов: 0 0 1 1 0 0 0 1
Второй вариант
m=0 n=1 cod=16 Номер битов: 7 6 5 4 3 2 1 0 Значение битов: 0 0 0 1 0 0 0 0
Ключевые термины
Битовое поле – это элемент структуры, определенный как некоторое число битов, обычно меньшее, чем длина машинного слова.
Размещение битовых полей – это порядок следования битов в машинных словах.
Ширина битового поля – это количество битов, занимаемых полем.
Краткие итоги
- В качестве элемента структуры или объединения может быть использовано битовое поле.
- Вне структур или объединений битовые поля использовать нельзя.
- Существует три способа доступа к битовым полям.
- К битовым полям нельзя обратиться по адресу размещения в памяти.
- Расположение битовых полей зависит от реализации.
- Ширина битовых полей не должна превосходить длины машинного слова. Допускается использование битового поля нулевой ширины.
- Для битовых полей определена операция присваивания.