Программирование на C и C++

Онлайн справочник программиста на C и C++

Объединения

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

union union_type {
int i; char ch;
};

Как и для структур, можно объявить переменную, поместив ее имя в конце определения или используя отдельный оператор объявления. Для объявления переменной cnvt объединения union_type следует написать:

union union_type cnvt;

В cnvt как целое число i, так и символ ch занимают один участок памяти. (Конечно, i занимает 2 или 4 байта, a ch — только 1.) Рисунок показывает, как i и ch разделяют один участок памяти (предполагается наличие 16-битных целых). Можно обратиться к данным, сохраненным в cnvt, как к целому числу, так и к символу.

Рисунок: Использование переменными i и cnvt, (размер переменной целого типа принимается равным 16 битам)

Когда объявлено объединение, компилятор автоматически создает переменную достаточного размера для хранения наибольшей переменной, присутствующей в объединении.

Для доступа к членам объединения используется синтаксис, применяемый для доступа к структурам - с помощью операторов «точка» и «стрелка». Чтобы работать с объединением напрямую, надо использовать оператор «точка». Если к переменной объединения обращение происходит с помощью указателя, надо использовать оператор «стрелка». Например, для присваивания целого числа 10 элементу i объединения cnvt следует написать:

cnvt.i = 10;

Использование объединений помогает создавать машинно-независимый (переносимый) код. Поскольку компилятор отслеживает настоящие размеры переменных, образующих объединение, уменьшается зависимость от компьютера. Не нужно беспокоиться о размере целых или вещественных чисел, символов или чего-либо еще.

Объединения часто используются при необходимости преобразования типов, поскольку можно обращаться к данным, хранящимся в объединении, совершенно различными способами. Рассмотрим проблему записи целого числа в файл. В то время как можно писать любой тип данных (включая целый) в файл с помощью fwrite(), для данной операции использование fwrite() слишком «жирно». Используя объединения, можно легко создать функцию, побайтно записывающую двоичное представление целого в файл. Хотя существует несколько способов создания данной функции, имеется один способ выполнения этого с помощью объединения. В данном примере предполагается использование 16-битных целых. Объединение состоит из одного целого и двухбайтного массива символов:

union pw {
int i;
char ch[2];
};

Объединение позволяет осуществить доступ к двум байтам, образующим целое, как к отдельным символам. Теперь можно использовать pw для создания функции write_int(), показанной в следующей программе:

#include <stdio.h>
#include <stdlib.h>
union pw {
int i;
char ch[2];
};

int write_int(int num, FILE *fp);

int main()
{
FILE *fp;
fp = fopen("test.tmp", "w+");

if(fp==NULL) {
printf("Cannot open file. \n");
exit(1);
}

write_int(1000, fp);
fclose(fp);
return 0;
}

/* вывод целого с помощью объединения */

int write_int (int num, FILE *fp) {
union pw wrd;
wrd.i = num;
putс(wrd.ch[0], fp); /* вывод первой половины */
return putc(wrd.ch[1], fp); /* вывод второй половины */
}

Хотя write_int() вызывается с целым, она использует объединение для записи обеих половинок целого в дисковый файл побайтно.