1.16. Структуры, объединения, битовые поля

Структура - это объединенное в единое целое множество семантически свя­занных именованных элементов разных типов (аналог записей в языке PASCAL). Существует несколько вариантов описания структур, во многих случаях при этом используется структурный шаблон. Структурный шаблон описывается в виде:

struct имя шаблона { описания элементов } ; Элементы структуры, описываемые в таком операторе - это то же самое, что поля записей в языке PASCAL. Структурную переменную можно описать, используя предварительно описанный шаблон:

struct имя шаблона имена переменных ; Можно объединить описания шаблона и переменной:

struct имя шаблона { описания элементов } имена переменных ;

или

struct { описания элементов } имена переменных ; В этом случае шаблон может и не иметь имени. Имя шаблона не является име­нем типа, его нельзя использовать в описаниях без слова struct, но можно дать имя структурному типу, используя оператор typedef.

Структуры, как и любые другие переменные, можно инициализировать. До­пускаются массивы структур, вложенные структуры и указатели на структуры. Пример описания структурных переменных:

struct stl {int Num; unsigned char Ch; char St[64];};

struct stl а={-11,'НУ'123456789м}, b={0,'U',MM},

c={777,'\a7'This is C structure"}, *p1=&c;

Обращение к элементу структуры осуществляется так же, как в языке

PASCAL :

имя структуры . имя элемента

Для указателей на структуры определена специальная операция косвенной адресации: -> , которая имеет самый высокий приоритет среди всех операций, она используется для обращения к элементу структуры по адресу:

указатель -> имя элемента Например: p1->Ch , p1->St[0] . Можно заменить операцию косвенной адресации операцией "значение": (*p1).Ch , (*p1).St[0] .

В смысле взаимодействия с функциями структуры рассматриваются как ска­лярные объекты, поэтому допускаются параметры функций - структуры и функ­ции, возвращающие структуры. Для однотипных структур определена операция присваивания = . К структурным переменным применима операция "адрес" &.

Объединение - это объект, который может содержать (попеременно) данные разных типов (фактически объединение является структурой, все элементы кото­рой имеют нулевое смещение относительно ее базового адреса). Для объедине­ния резервируется память по самому большому элементу. Полным аналогом объ­единений являются вариантные поля записей в языке PASCAL.

Описание объединений и обращение к их элементам аналогично соответст­вующим действиям со структурами, но при этом ключевое слово struct заменяет­ся на union. Инициализировать объединение можно только значением, имеющим тип первого из его элементов.

Битовое поле - это последовательность битов, лежащих внутри одного или нескольких машинных слов. Описание поля имеет вид:

struct { [ тип ] [ имя ] : длина ; .................... } ;

Тип элемента поля всегда int или unsigned. Неименованные элементы можно использовать для выравнивания (пропуска битов). Например, опишем объект, позволяющий осуществлять прямой доступ к любому биту младшего байта слова и к старшему биту:

struct BitStr { unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; unsigned b5:1; unsigned b6:1; unsigned b7:1; unsigned b8:1; :7; unsigned UP:1; };

union Word { unsigned N; struct BitStr b;}; union Word Number={0X3FE6};

printf("%u%u%u%u%u%u%u%u",Number.b.b1,Number.b.b2, Num-ber.b.b3, Num-ber.b.b4,Number.b.b5,Number.b.b6,Number.b.b7,Number.b.b8);

printf(" Up bit=%u",Number.b.UP);

В арифметических выражениях элементы битовых полей рассматриваются как целые числа.