Как и при использовании структур, при объявлении объединения не определяется ни одна переменная. Переменную можно объявить, разместив ее имя в конце объявления либо воспользовавшись отдельной инструкцией объявления. Чтобы объявить переменную объединения именем u_var типа utype, достаточно записать следующее:
utype u_var;
В переменной объединения u_var как переменная i типа short int, так и символьная переменная ch разделяют одну и ту же область памяти. (Безусловно, переменная i занимает два байта, а символьная переменная ch использует только один.) Как переменные i и ch разделяют одну область памяти, показано на рис. 10.2.
При объявлении объединения компилятор автоматически выделяет область памяти, достаточную для хранения в объединении переменных самого большого по объему типа.
Чтобы получить доступ к элементу объединения, используйте тот же синтаксис, который применяется и для структур: операторы "точка" и "стрелка". При непосредственном обращении к объединению (или посредством ссылки) используется оператор "точка". Если же доступ к переменной объединения осуществляется через указатель, используется оператор "стрелка". Например, чтобы присвоить букву 'А' элементу ch объединения u_var, достаточно использовать такую запись.
u_var.ch = 'А';
В следующем примере функции передается указатель на объединение u_var. В теле этой функции с помощью указателя переменной i присваивается значение 10.
// ...
func1(&u_var); // Передаем функции func1() указатель на объединение u_var.
// ...
}
void fund (utype *un)
{
un->i = 10; /* Присваиваем число 10 члену объединения u_var с помощью указателя. */
}
Поскольку объединения позволяют вашей программе интерпретировать одни и те же данные по-разному, они часто используются в случаях, когда требуется необычное преобразование типов. Например, следующая программа использует объединение для перестановки двух байтов, которые составляют короткое целочисленное значение. Здесь для отображения содержимого целочисленных переменных используется функция disp_binary(), разработанная в главе 9. (Эта программа написана в предположении, что короткие целочисленные значения имеют длину два байта.)
// Использование объединения для перестановки двух байтов в рамках короткого целочисленного значения.
#include <iostream>
using namespace std;
void disp_binary(unsigned u);
union swap_bytes {
short int num;
char ch[2];
};
int main()
{
swap_bytes sb;
char temp;
sb.num = 15; // двоичный код: 0000 0000 0000 1111
cout << "Исходные байты: ";
disp_binary(sb.ch[1]);
cout << " ";
disp_binary(sb.ch[0]);
cout << "\n\n";
// Обмен байтов.
temp = sb.ch[0];
sb.ch[0] = sb.ch[1];
sb.ch[1] = temp;
cout << "Байты после перестановки: ";
disp_binary(sb.ch[1]);
cout << " ";
disp_binary(sb.ch[0]);
cout << "\n\n";
return 0;
}
// Отображение битов, составляющих байт.
void disp_binary(unsigned u)
{
register int t;
for(t=128; t>0; t=t/2)
if(u & t) cout << "1 ";