Объединение – это частный случай структуры, все поля которой имеют нулевое смещение от начала, то есть занимают одно и то же место в памяти, достаточное для самого длинного поля, поэтому работать в данный момент программа может только с одним из полей. Описание шаблона и доступ к полям выполняется так же, как и для структуры, но в каждый момент времени в переменной типа union храниться только одно значение, о чем должен помнить сам программист. Если в переменную записано значение одного типа, а используется другое, это приводит к неправильным результатам. Разрешается создание и массива объединений. Объединение может инициализироваться только первым описанным полем.
Пример. Описание и инициализация переменной для объединения.
struct field2 { /* шаблон структуры */
int tab; /* поля структуры */
char count[15];
};
union tabl { /* шаблон объединения */
unsigned char name [20]; /* поле объединения */
struct field2 ff; /* поле – вложенная структура */
} pt = ”Петров”; /* переменная с инициализацией */
Существует ряд весьма популярных применений объединения. Прежде всего это доступ к одной и той же области памяти либо как к целому, либо к отдельным частям.
|
|
Пример. Требуется ввести в диалоге символ, преобразовать его в двоичный код и вывести на экран символ и его двоичный код, используя объединение (union simb) с полями для кода символа и структуры байта с битовыми полями, а также функцию анализа, преобразования (конвертации) и вывода битов двоичного кода символа (convert ()).
Программа:
#include<stdio.h>
#include<conio.h>
struct byte { /*описание структуры байта с битовыми полями */
unsigned a:1; /* младший бит */
unsigned b:1;
unsigned c:1;
unsigned d:1;
unsigned e:1;
unsigned f:1;
unsigned g:1;
unsigned h:1; /* старший бит */
};
union symb { /* описание объединения */
unsigned char ch; /* поле для символа */
struct byte bit; /* поле для двоичных разрядов байта */
} symbol; /* переменная объединения */
void convert (union symb); /* прототип функции конвертации */
void main() /* главная функция */
{ clrscr (); /* очистка экрана */
puts (“Вводите символы нажатием клавиш.”);
puts (“Для окончания ввода нажмите ПРОБЕЛ.”);
do /* цикл ввода символов и вывода их кодов */
{ symbol.ch=getche(); /* чтение с отображением очередного символа */
printf(“: “); /* вывод разделителя */
convert (symbol); /* конвертация символа и вывод двоичного кода */
} while (symbol.ch!= “ “); /* условие продолжения цикла */
}
void convert (union symb s); /* функция конвертации символа в код */
{ /* Проверка значения бита и вывод его символа на экран: */
if (s.bit.h) printf (“1”); else printf (“0”);
if (s.bit.g) printf (“1”); else printf (“0”);
if (s.bit.f) printf (“1”); else printf (“0”);
if (s.bit.e) printf (“1”); else printf (“0”);
if (s.bit.d) printf (“1”); else printf (“0”);
if (s.bit.c) printf (“1”); else printf (“0”);
if (s.bit.b) printf (“1”); else printf (“0”);
if (s.bit.a) printf (“1”); else printf (“0”);
printf(“\n”); /* переход к новой строке */
}
Результаты программы:
Вводите символы нажатием клавиш.
Для окончания нажмите ПРОБЕЛ.
0: 00110000
1: 00110001
9: 00111001
a: 01100001
b: 01100010
A: 01000001
: 00100000 /* код ПРОБЕЛА */