Опубликован: 02.02.2011 | Доступ: свободный | Студентов: 3381 / 990 | Оценка: 4.43 / 3.57 | Длительность: 33:06:00
Специальности: Программист
Лекция 18:

Объединения

< Лекция 17 || Лекция 18: 123 || Лекция 19 >
Аннотация: В лекции рассматриваются определения, способы объявления, объединений как частного случая структур, методы доступа к данным объединения, размещение объединений и определение их размера в памяти, использование объединений при объявлении переменных с изменяемой структурой.

Цель лекции: изучить понятия, оформления и определения объединений, доступ к элементам объединения, указатели на объединения и научиться решать задачи с использованием объединений на языке C++.

Объединение – это частный случай структуры.

Объединение подобно структуре, однако в каждый момент времени может использоваться (или, другими словами, быть ответным) только один из элементов объединения.

Объединение (смеси)объект, который в каждый момент времени содержит один из нескольких элементов различных типов.

Объединение является структурой данных, члены которой расположены по одному и тому же адресу. Поэтому размер объединения равен размеру его наибольшего члена. В любой момент времени объединение хранит значение только одного из членов.

Объявление объединения определяет имя переменной объединения и специфицирует множество переменных, называемых элементами объединения, которые могут быть различных типов. Переменная с типом объединения запоминает любую отдельную величину, определяемую набором элементов объединения.

Определение объединений

Все компоненты объявления структур, такие как шаблоны, имена типов, имена элементов и т.д. применимы и при объявлении объединений. Единственное отличие состоит в том, что при объявлении объединения вместо ключевого слова struct используется union.

Синтаксис:

union [ИмяОбъединения] { 
                        ОпределенияЭлементов; 
                       } ОбозначениеОбъединения;

где unionспецификатор типа; ИмяОбъединенияидентификатор; ОпределенияЭлементов – совокупность описаний объектов, каждый из которых служит прототипом одного из элементов объединений.

Например:

union {
       char hh[2];
       int ii;
       } CC;

Главной особенностью объединения является то, что для каждого из объявленных элементов выделяется одна и та же область памяти, т.е. они перекрываются. Хотя доступ к этой области памяти возможен с использованием любого из элементов, элемент для этой цели должен выбираться так, чтобы полученный результат не был бессмысленным.

Как и для структурных типов, с помощью typedef можно вводить обозначения объединяющих типов.

Синтаксис:

typedef union [ИмяОбъединения] 
        {
         ОпределенияЭлементов; 
        } ОбозначениеОбъединения;

Например:

typedef union uni {
                   double d;
                   int i[4];
                   char ch[8];
                  } u_name;

На основе такого определения типа можно вводить конкретные объединения двумя способами:

union uni a, b;
u_name x, y;

Объединение применяется для следующих целей:

  • инициализации используемого объекта памяти, если в каждый момент времени только один объект из многих является активным;
  • интерпретации основного представления объекта одного типа, как если бы этому объекту был присвоен другой тип.

Доступ к элементам объединения (полям данных)

Для обращения к элементу объединения используются те же конструкции, что и для обращения к элементу структуры:

ИмяОбъединения.ИмяЭлемента
(* УказательНаОбъединение).ИмяЭлемента
УказательНаОбъединение->ИмяЭлемента

Например:

СС.hh
(*pin).mas
pin–>mas

Чтобы работать с объединением напрямую, надо использовать оператор "точка" (.). Если к переменной объединения обращение происходит с помощью указателя, надо использовать оператор "стрелка" ( -> ).

Определение размера памяти, выделяемой под объединение

Память, которая соответствует переменной типа объединение, определяется величиной для размещения любого отдельного элемента объединения.

В отличие от структуры, объединение может в любой момент времени содержать только один из своих элементов. Объединение позволяет использовать одну область памяти для хранения различных видов данных в разные моменты времени. Фактически, объединение – это структура, в которой все поля начинаются со смещением 0, таким образом, поля накладываются друг на друга.

Когда используется наименьший элемент объединения, то переменная типа объединения может содержать неиспользованное пространство. Все элементы объединения запоминаются в одном и том же пространстве памяти переменной, начиная с одного и того же адреса. Запомненные значения затираются каждый раз, когда присваивается значение очередного элемента объединения.

Например:

struct s_tag {
              char c;
              int i;
              double d;
             } s_item;
union u_tag {
             char c;
             int i;
             double d;
            } u_item;


Все поля объединения располагаются по одному и тому же адресу. Размер объединения равен наибольшей из длин его полей. То есть память, которая соответствует переменной типа объединения, определяется величиной, необходимой для размещения наиболее длинного элемента объединения. Когда используется элемент меньшей длины, то переменная типа объединения может содержать неиспользуемую память. Объединения применяются для экономии памяти, если известно, что другие поля не потребуются. Также объединение обеспечивает доступ к одному участку памяти с помощью переменных разного типа.

Пример 1. Определение размера структуры и объединения.

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {
  struct s_tag {
                char c;
                int i;
                double d;
               } s_item;
  union u_tag {
               char c;
               int i;
               double d;
              } u_item;
  printf("Размер структуры = %d\n", sizeof(s_item));
  printf("Размер объединения = %d\n", sizeof(u_item)); 
  system("pause");
  return 0;
}

Результат выполнения программы:

Размер структуры = 16 
Размер объединения = 8

Например:

union { 
       char fio[30];
       char adres[80];
       int vozrast;
       int telefon; 
      } inform;
union {  
       int ax;
       char al[2]; 
      } ua;

При использовании объекта inform типа union можно обрабатывать только тот элемент, который получил значение, т.е. после присвоения значения элементу inform.fio, не имеет смысла обращаться к другим элементам. Объединение ua позволяет получить отдельный доступ к младшему ua.al[0] и к старшему ua.al[1] байтам числа ua.ax.

< Лекция 17 || Лекция 18: 123 || Лекция 19 >
Денис Курбатов
Денис Курбатов
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!