Пример 1.
void main()
{
struct TS
{float f; int K;
} S={25.6, 22};
/* Совместное объявление структуры и инициализация её полей. */
printf("%d\n", sizeof(TS));
/* Выведем число 8 — объём занимаемой памяти для размещения всех полей структуры: 4 байта для вещественного числа и столько же для целого */
cout<<endl<<S.f; // Выведем число 25.6
cout<<endl<<hex<<S.K; // Выведем число 16
/* Манипулятор hex используется для ввода и вывода данных (здесь для вывода целого числа) в шестнадцатеичной системе счисления (2210=1616 )*/
/* Рассмотрим аналогичный код для работы с объединением. Объявим теперь тип объединения (TU) и переменную этого типа (U).: */
union TU1
{float f; int K;
} U1= {25.6};
/* Объявление объединения аналогично объявлению структуры, только вместо struct записывается union. Но инициализацию в объединении можно выполнить только для одного поля ! */
cout<< endl<<sizeof(U1)<<endl; // Выводится число 4
cout<<endl<<U1.f; // Число 25.6
cout<<endl<<hex<<U1.K; // Выводится 41cccccd
getch();
}
5.3. Сравнение объединения и структуры.(+)
Основное отличие объединения от структуры в том, что объединение позволяет нескольким переменным различных типов занимать один участок памяти. Его объём равен количеству байт, необходимых для размещения самого “длинного ” поля. В нашем примере оба поля имеют одинаковый размер и занимают четыре байта оперативной памяти. Переменная f и K размещаются в одной и той же области памяти. Содержимое этих четырёх байт рассматривается как вещественное число, если используем U.f или как целое число с идентификатором U.K. Число 25.6 в формате float в четырёх байтах будет представлено так: 01000001110011001100110011001101. А то, что получили при выводе U.K , т.е. 41cccccd —это тот же “набор нулей и единиц” в шестнадцатеричной системе счисления, так как при выводе использовали манипулятор вывода hex.
Рассмотрим пример 2.
union TU2
{int N; short n; char ch[2];
} U2= {0x12345678};
cout<< sizeof(U2)<<endl;
cout<<hex<<U2.N<<endl<<” “<<U2.n<<endl;
cout<<” “<<U2.ch[1]<<U2.ch[0]<<endl;
В результате получим:
4
12345678
5678
Vx
Анализ этого и других результатов показывает, что в современных системах С++ поля объединения выравниваются по правому краю. Выполнение оператора printf("%x %x", 'x', 'V'); показывает, что символ ‘x’ имеет код 7816, а 'V' — код 5616.
Одни и те же четыре байта в программе обозначаются следующим образом:
|----------------------------- U2.N-------------------------|
|------------- U2.n----------|
В последнем “правом” байте находится символ U2.ch[0], а в предпоследнем — символ U2.ch[1].
Элементом (полем) объединения может быть структура. Рассмотрим следующий пример 3.
union TU3 // Тип объединения
{ // Анонимное объявление структуры в объединении
struct
{ unsigned short lo;
unsigned short hi;
} w;
long N;
};
// Раздельное объявление переменной типа объединение.
TU3 U3; U3.N=0x12345678L; // или U3.N=0x12345678;
cout<< hex<<endl<<U3.N<<endl;
cout<<hex<<U3.w.lo<<endl;
cout<<hex<<U3.w.hi<<endl;
В результате получим:
12345678
5678
1234
Здесь четыре байта обозначаются следующим образом:
|----------------------- U3.N-------------------------------|
|-----------U3.w.hi----------|---------- U3.w.lo----------|
C помощью объединения можно, например, “посмотреть” каждый байт целого четырёхбайтного числа.