Операционная система UNIX. Руководство программиста

     

Описания структур и объединений


Структура есть объект, состоящий из последовательности именованных элементов. Любой элемент может иметь произвольный тип. Объединение есть объект, который может в каждый момент времени содержать один из нескольких элементов. Спецификаторы структур и объединений имеют одинаковый вид:

спецификатор_структуры_или_объединения: struct { список_структ_описаний }

struct идентификатор { список_структ_описаний }

struct идентификатор union { список_структ_описаний }

union идентификатор { список_структ_описаний }

union идентификатор

Список_структ_описаний - это последовательность описаний элементов структуры или объединения:

список_структ_описаний: структ_описание структ_описание список_структ_описаний

структ_описание: спецификатор_типа список_структ_описателей ;

список_структ_описателей: структ_описатель структ_описатель , список_структ_описателей

Чаще всего структ_описатель - это именно описатель элемента структуры или объединения. Кроме того, элемент структуры может содержать набор бит заданной длины. Такой элемент называют битным полем; его длина, неотрицательное константное_выражение, отделяется от имени поля двоеточием.

структ_описатель: описатель описатель : константное_выражение : константное_выражение

В пределах структуры описываемые объекты имеют адреса, возрастающие соответственно порядку описаний. Начало каждого элемента структуры, не являющегося битным полем, выравнивается в соответствии с его типом; поэтому в структуре могут быть и неименованные промежутки. Битные поля упаковываются в стандартные для данной машины слова, хранящие объекты типа int. Поля не могут пересекать границ слов; отсюда следует, что поле не может быть длиннее слова. Если в текущем слове после размещения предыдущих полей осталось слишком мало места, очередное поле будет храниться, начиная с границы следующего слова.



Структ_описатель без описателя, состоящий только из двоеточия и константного_выражения, обозначает неименованное битное поле; его удобно использовать как заполнитель для согласования с установленным извне расположением данных. Как особый случай, битное поле длины 0 специфицирует выравнивание следующего поля в соответствии с реализационно-зависимыми границами.


Язык не накладывает ограничений на типы объектов, описываемых как битные поля. Следует учитывать, что поля типа int будут рассматриваться как беззнаковые, если их длина меньше слова. По этой причине настоятельно рекомендуется явно описывать подобные поля как unsigned, чтобы текст программы соответствовал реальному положению вещей. Не бывает массивов битных полей, к ним нельзя применять операцию вычисления адреса, &, поэтому не бывает и указателей на битные поля.
Объединение можно представлять себе как структуру, все элементы которой располагаются с одним и тем же отступом 0 от начала и размер которой достаточен, чтобы вместить любой из элементов. В каждый момент времени в объединении может храниться единственный элемент.
Спецификатор_структуры_или_объединения во второй форме, то есть
struct идентификатор { список_структ_описаний }
union идентификатор { список_структ_описаний }
описывает идентификатор, являющийся тегом структуры (тегом объединения), специфицируемой списком_структ_описаний. Последующие описания могут затем использовать третью форму спецификатора:
struct идентификатор union идентификатор
Теги структур позволяют описывать структуры, ссылающиеся сами на себя. Они позволяют также задать длинную часть описания однажды, а использовать многократно. Недопустимо описывать структуры или объединения, содержащие экземпляры самих себя; однако структура или объединение может содержать указатель на экземпляр данного типа.
Третью форму спецификатора_структуры_или_объединения можно использовать перед описанием, дающим полную спецификацию структуры или объединения в случаях, когда не требуется знать размер структуры или объединения. Размер не важен в двух ситуациях: когда описывается указатель на структуру или объединение и когда при помощи конструкции typedef описывается имя, являющееся синонимом структуры или объединения. Тем самым появляется возможность описать, например, пару структур, содержащих указатели друг на друга.
Имена элементов и теги не конфликтуют между собой и с именами обычных переменных. Одно и то же имя не может дважды использоваться в одной структуре, однако в пределах одной области видимости в нескольких разных структурах можно использовать одинаковые имена элементов.
Следующая спецификация, задающая бинарное дерево, является несложным, но важным примером описания структуры:
struct tnode { char tword [20]; int count; struct tnode *left; struct tnode *right; };
Структура содержит массив из 20 символов, целое число и два указателя на аналогичные структуры. Затем с помощью конструкции
struct tnode s, *sp;
можно описать объект s - структуру данного сорта и sp - указатель на структуру данного сорта. В соответствии с этими описаниями выражение
sp->count
обозначает поле count структуры, на которую указывает sp;
s.left
есть указатель на левое поддерево в структуре s;
s.right->tword [0]
есть первый символ поля tword в правом поддереве s.


Содержание раздела