
- •Структура как пользовательский тип и совокупность данных
- •Определение шаблона структуры и структурной переменной
- •Расположение структурных переменных в памяти
- •Инициализация структурных переменных
- •Вложенные структуры
- •Операции над структурными переменными
- •Массив структур
- •Структура в качестве аргумента функции
- •Примеры работы со структурами
- •person_list
- •Объединение как пользовательский тип и совокупность данных
- •Определение объединения и переменной объединяющего типа
- •Использование перечисляемого типа для обращения к полям объединения
- •Битовые поля структур и объединений
- •Определение битовых полей
- •Формирование кода символа с помощью битовых полей объединения
- •Формирование байта и вывод на экран его двоичного представления
Битовые поля структур и объединений
Определение битовых полей
Язык С++ допускает использование в структурах и объединениях в качестве полей данных особого типа полей – битовых. Каждое битовое поле представляет целое или беззнаковое целое значение, занимающее в памяти фиксированное число битов. Число связанных бит – ширина поля.
Общий синтаксис описания битового поля: тип_поля [имя_поля]: ширина_поля;
Члены битовых полей могут иметь значения базовых целых типов (знаковых или беззнаковых). Эти ключевые слова записываются в поле «тип_поля». Для переносимости программ лучше указывать служебные слова 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

{
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
} 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