Очень часто некоторые объекты программы относятся к одному и тому же классу, отличаясь лишь некоторыми деталями. Рассмотрим, например, представление геометрических фигур. Общая информация о фигурах может включать такие элементы, как площадь, периметр. Однако соответствующая информация о геометрических размерах может оказаться различной в зависимости от их формы.
Рассмотрим пример, в котором информация о геометрических фигурах представляется на основе комбинированного использования структуры и объединения.
struct figure {
double area,perimetr; /* общие компоненты */
int type; /* признак компонента */
union /* перечисление компонент */
{ double radius; /* окружность */
double a[2]; /* прямоугольник */
double b[3]; /* треугольник */
} geom_fig;
} fig1, fig2 ;
В общем случае каждый объект типа figure будет состоять из трех компонентов: area, perimetr, type. Компонент type называется меткой активного компонента, так как он используется для указания, какой из компонентов объединения geom_fig является активным в данный момент. Такая структура называется переменной структурой, потому что ее компоненты меняются в зависимости от значения метки активного компонента (значение type).
Отметим, что вместо компоненты type типа int, целесообразно было бы использовать перечисляемый тип. Например, такой
enum figure_chess { CIRCLE,
BOX,
TRIANGLE } ;
Константы CIRCLE, BOX, TRIANGLE получат значения соответственно равные 0, 1, 2. Переменная type может быть объявлена как имеющая перечислимый тип :
enum figure_chess type;
В этом случае компилятор СИ предупредит программиста о потенциально ошибочных присвоениях, таких, например, как
figure.type = 40;
В общем случае переменная структуры будет состоять из трех частей: набор общих компонент, метки активного компонента и части с меняющимися компонентами. Общая форма переменной структуры, имеет следующий вид:
struct { общие компоненты;
метка активного компонента;
union { описание компоненты 1 ;
описание компоненты 2 ;
:::
описание компоненты n ;
} идентификатор-объединения ;
} идентификатор-структуры ;
Пример определения переменной структуры с именем helth_record
struct { /* общая информация */
char name [25]; /* имя */
int age; /* возраст */
char sex; /* пол */
/* метка активного компонента */
/* (семейное положение) */
enum merital_status ins;
/* переменная часть */
union { /* холост */
/* нет компонент */
struct { /* состоит в браке */
char marripge_date[8];
char spouse_name[25];
int no_children;
} marriage_info;
/* разведен */
char date_divorced[8];
} marital_info;
} health_record;
enum marital_status { SINGLE, /* холост */
MARRIGO, /* женат */
DIVOREED /* разведен */
} ;
Обращаться к компонентам структуры можно при помощи ссылок: