Пример 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 помощью объединения можно, например, “посмотреть” каждый байт целого четырёхбайтного числа.