Объединения. Ключевое слово union. Примеры объявления и использования объединений
Содержание
- Вопрос/ответ
- 1. Что такое объединение в языке C++? Для чего используются объединения?
- 2. Как выглядит общая форма объявления типа (шаблона) объединения? Ключевое слово union
- 3. Что такое длина объединения? Как вычисляется длина объединения?
- 4. Как объявить тип (шаблон) объединения и переменную этого типа? Пример
- 5. Как осуществляется доступ к полям объединения?
- 6. Пример объявления и использования указателя (*) на объединение
- 7. Как объявить вложенные объединения (структуры, классы) в шаблоне объединения? Пример
- 8. Как описать массив объединений? Пример
- 9. Какие особенности применения операции sizeof() для объединений и структур?
- Связанные темы
Поиск на других ресурсах:
1. Что такое объединение в языке C++? Для чего используются объединения?
Объединение – это группирование переменных, которые разделяют одну и ту же область памяти. В зависимости от интерпретации осуществляется обращение к той или другой переменной объединения. Все переменные, что включены в объединение начинаются с одной границы.
Объединение позволяет представить в компактном виде данные, которые могут изменяться. Одни и те же данные могут быть представлены разными способами с помощью объединений.
Точно также как и структуры, объединения требуют объявления типа (шаблона) и объявления переменной этого типа.
2. Как выглядит общая форма объявления типа (шаблона) объединения? Ключевое слово union
Объявление объединения (типа объединения или шаблона объединения) начинается с ключевого слова union.
union имя_типа_объединения
{
тип переменная1;
тип переменная2;
...
тип переменнаяN;
};
где
- имя_типа_объединения – непосредственно имя новосозданного типа;
- переменная1, переменная2, переменнаяN – переменные, которые есть полями объединения. Эти переменные могут быть разных типов;
- тип – тип переменной, который есть полем объединения.
Тип переменной может быть:
- базовым типом, принятым в языке C++/CLI;
- тип структура;
- тип объединения;
- тип класс.
3. Что такое длина объединения? Как вычисляется длина объединения?
Длина объединения – это размер памяти в байтах, которая выделяется для одной переменной этого типа объединения.
Длина объединения вычисляется как максимум из всех длин (размеров в байтах) отдельных полей шаблона. Следует напомнить, что одно поле – это объявление одной переменной в объединении (см. п. 2).
4. Как объявить тип (шаблон) объединения и переменную этого типа? Пример
Пусть задан тип объединения, которое содержит переменные типов с плавающей точкой
// объявление типа "объединение Floats" union Floats { float f; // рассматривается 4 байта double d; // рассматривается 8 байт };
Тип объединения Floats содержит 2 переменные с именами f и d. Переменная f есть типа float, переменная d есть типа double. Для переменной f типа float рассматривается (принимается во внимание) 4 байта. Для переменной d типа double принимается во внимание 8 байт, так как компилятор выделяет для этого типа именно 8 байт.
Чтобы использовать объединение Floats в другом программном коде (методе, обработчике события и т.п.) нужно объявить переменную типа Floats как показано ниже
Floats Fl; int d; Fl.f = 20.5; // Fl.d не определено Fl.d = -100.35; // теперь Fl.f не определено d = sizeof(Fl); // d = 8
Поскольку размещение переменных в памяти условно начинается с одного адреса, то для переменной Fl типа Floats выделяется 8 байт памяти. Это связано с тем, что переменная типа double требует больше памяти для своего представления чем переменная типа float.
На рисунке 1 отображено размещение (интерпретация) переменных f, d из объединения Floats.
Рис. 1. Представление переменных f, d в объединении Floats
5. Как осуществляется доступ к полям объединения?
Доступ к полям объединения осуществляется так же, как и для структуры:
- с помощью символа ‘ . ‘;
- с помощью последовательности символов ‘->’ в случае, когда объявлена переменная-указатель на объединение.
6. Пример объявления и использования указателя (*) на объединение
Работа объединений с неуправляемыми (*) указателями точно такая же, как и работа структур с неуправляемыми указателями.
В нижеследующем примере объявляется неуправляемый указатель на объединение типа Ints
// указатель на объединение Ints *p; // неуправляемый указатель // выделить память для объединения p = new Ints; // доступ к полям с помощью указателя pI->a = 200; pI->b = 3400;
7. Как объявить вложенные объединения (структуры, классы) в шаблоне объединения? Пример
Шаблон объединения может включать поля, что есть структурами, объединениями и классами.
В примере ниже объявляется шаблон объединения с именем Types, содержащий два вложенных объединения Floats и Ints, структуру ArrayOfChars и класс MyPoint.
Объявление структур и объединений имеет следующий вид
// объединение целочисленных типов union Ints { unsigned short int a; unsigned int b; unsigned long int c; }; // структура, содержащая 2 строки struct ArrayOfChars { char A[10]; char B[8]; }; // объявление типа "объединение Floats" union Floats { float f; // рассматривается 4 байта double d; // рассматривается 8 байт };
Объявление шаблона класса имеет следующий вид:
// класс объявляется в отдельном модуле, например MyPoint.h #pragma once class MyPoint { public: int x; int y; // методы класса int GetX(void) { return x; } int GetY(void) { return y; } void SetXY(int nx, int ny) { x = nx; y = ny; } };
Объявление типа объединение Types с вложенными сложными типами Ints, Floats, ArrayOfChars, MyPoint.
// подключить модуль с объявленным классом MyPoint #include "MyPoint.h" ... // объявление типа "объединение Types" union Types { Floats Fl; // объединение Ints I; // объединение ArrayOfChars A; // структура MyPoint MP; // класс };
Использование объединения Types в некотором программном коде:
// объявить переменную типа "объединение Types" Types T; // изменить значения полей переменной T T.Fl.f = (float)20.35; // объединение Floats T.I.b = 230; // объединение Ints T.A.A[2] = 'A'; // структура ArrayOfChars T.MP.SetXY(3,8); // класс MyPoint int d; d = T.MP.GetX(); // d = 3
8. Как описать массив объединений? Пример
// Пример объявления и использования массива объединений Floats F[5]; // объявляется массив из 5 объединений типа Floats // заполнение значений полей for (int i=0; i<5; i++) { F[i].d = i*0.2 + i*i; }
9. Какие особенности применения операции sizeof() для объединений и структур?
В программах на C++ для определения размера переменной типа «структура» или «объединение» обязательно нужно использовать операцию sizeof. Определение размера «вручную» есть ошибочным поскольку:
- размеры некоторых встроенных типов (например тип int) могут быть разными для разных компьютеров. Например, на одних платформах для типа int будет выделено 2 байта, на других 4 байта;
- компилятор делает так называемое «выравнивание памяти» на границе слова (2 байта) или абзаца (16 байт). Например, если компилятор делает выравнивание на границе абзаца, то структура (объединение) типа ArraysOfChars:
// структура, содержащая 2 строки struct ArrayOfChars { char A[10]; char B[8]; };
может занимать в памяти 24 байта. Так как для массива A выделяется 16 байт а не 10 байт. Компилятор дополнительно выделяет 6 байт чтобы реализовать выравнивание на границе абзаца.
Таким образом, использование операции sizeof() для определения типа структуры или объединения гарантирует переносность программного кода.
Связанные темы
- Структуры. Составные типы данных. Шаблон структуры. Структурная переменная. Структуры в среде CLR. Объявление и инициализация структурной переменной
- Массивы. Определение массива. Одномерные массивы. Инициализация массива