Объединение – это специальный тип данных, доступный в D, который позволяет хранить различные типы данных в одном и том же месте памяти. Вы можете определить объединение со многими членами, но только один из них может содержать значение в определённый момент времени. Объединения предоставляют эффективный способ использования одного и того же места памяти для нескольких целей.
Чтобы определить объединение, вы должны использовать оператор union таким же образом, как и при определении структуры. Оператор union определяет для вашей программы новый тип данных с более чем одним членом. Формат оператора union выглядит следующим образом:
union [тег объединения] { объявление члена; объявление члена; ... объявление члена; } [Одна или несколько переменных типа union];
Тег объединения является необязательным, а объявление каждого члена является обычным объявлением переменной, таким как int i; или float f;, или любое другое допустимое определение переменной. В конце определения объединения до точки с запятой вы можете указать одну или несколько переменных типа этого объединения, которые являются необязательными. Вот как можно определить тип объединения с именем Data, который имеет три члена i, f и str:
union Data { int i; float f; char str[20]; } data;
Переменная типа Data может хранить целое число, число с плавающей точкой или массив символов. Это означает, что для хранения нескольких типов данных может использоваться одна и та же ячейка памяти. Вы можете использовать любые встроенные или определённые пользователем типы данных внутри объединения по своим потребностям.
Память, занимаемая объединением, будет достаточно большой, чтобы хранить наибольший член объединения. В приведенном выше примере тип данных будет занимать 20 байтов пространства памяти, поскольку это максимальное пространство, которое может быть занято массивом символов. В следующем примере отображается суммарный объём памяти, занимаемый указанным объединением:
import std.stdio; union Data { int i; float f; char str[20]; }; int main( ) { Data data; writeln( "Объём памяти, занимаемый данными : ", data.sizeof); return 0; }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Объём памяти, занимаемый данными : 20
Чтобы получить доступ к любому члену объединения, вы используете оператор доступа к члену (.). Оператор доступа в коде выглядит как точка между именем переменной объединения и членом объединения, к которому мы хотим получить доступ.
В следующем примере разъясняется использование объединения:
import std.stdio; union Data { int i; float f; char str[13]; }; void main( ) { Data data; data.i = 10; data.f = 220.5; data.str = "D Programming".dup; writeln( "размер data : ", data.sizeof); writeln( "data.i : ", data.i); writeln( "data.f : ", data.f); writeln( "data.str : ", data.str); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
размер data : 16 data.i : 1917853764 data.f : 4.12236e+30 data.str : D Programming
Здесь вы можете увидеть, что значения членов объединения i и f были повреждены, потому что место в памяти заняло последнее присвоенное переменной значение, и именно по этой причине значение члена str отобразилось хорошо.
Теперь давайте снова рассмотрим тот же пример, в котором мы теперь будем использовать одну переменную за один раз, что является основной целью использования объединений:
import std.stdio; union Data { int i; float f; char str[13]; }; void main( ) { Data data; writeln( "размер data : ", data.sizeof); data.i = 10; writeln( "data.i : ", data.i); data.f = 220.5; writeln( "data.f : ", data.f); data.str = "D Programming".dup; writeln( "data.str : ", data.str); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
размер data : 16 data.i : 10 data.f : 220.5 data.str : D Programming
Здесь значения всех членов отобразились хорошо, потому что одновременно используется только один из них.