Цель лекции: изучить понятия, оформления и определения объединений, доступ к элементам объединения, указатели на объединения и научиться решать задачи с использованием объединений на языке C++.
Объединение – это частный случай структуры.
Объединение подобно структуре, однако в каждый момент времени может использоваться (или, другими словами, быть ответным) только один из элементов объединения.
Объединение (смеси) – объект, который в каждый момент времени содержит один из нескольких элементов различных типов.
Объединение является структурой данных, члены которой расположены по одному и тому же адресу. Поэтому размер объединения равен размеру его наибольшего члена. В любой момент времени объединение хранит значение только одного из членов.
Объявление объединения определяет
Все компоненты объявления структур, такие как шаблоны, имена типов, имена элементов и т.д. применимы и при объявлении объединений. Единственное отличие состоит в том, что при объявлении объединения вместо ключевого слова struct используется .
Синтаксис:
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 типа можно обрабатывать только тот элемент, который получил значение, т.е. после присвоения значения элементу inform.fio, не имеет смысла обращаться к другим элементам. Объединение ua позволяет получить отдельный доступ к младшему ua.al[0] и к старшему ua.al[1] байтам числа ua.ax.
Допустимы массивы объединений и указатели на объединения. Объединения могут передаваться функции как параметры и возвращаться функцией.
Операции, применимые к структурам, аналогичны и для объединений, т.е. законны присваивание объединения и копирование его как единого целого, взятие адреса от объединения и доступ к отдельным его элементам.
Объединения часто включаются в структуры, один из элементов которых является ключом, указывающим тип хранимого в памяти элемента объединения.
Например:
//содержит информацию о работающих служащих и пенсионерах
struct mail {
char id; // a - active (), r - retired()
union {
struct {
char name[30];
char dept[10];
char location[3];
} active;
struct {
char name[30];
char street[20];
char city_state[3];
char zip[5];
} retired;
} info;
} person;
Структура типа ). При заполнении структуры этого active или объединения info. Поле id устанавливается равным 'a' или 'r' для указания фактически записанного в объединении элемента. При применении объединения используется меньше памяти, чем в случае применения структуры, которая имела бы идентичные поля, но некоторые из них не использовались бы.
(рис 17.1) Объединение как элемент структуры
Очень часто некоторые объекты программы относятся к одному и тому же классу, отличаясь лишь некоторыми деталями. В таких случаях используются переменные с изменяемой структурой. Рассмотрим, например, представление
Пример 2. Информация о геометрических фигурах представляется на основе комбинированного использования структуры и объединения.
struct figure {
double area,perimetr; // общие компоненты
int type; // признак компонента
union { // перечисление компонент
double radius; // окружность
double a[2]; // прямоугольник
double b[3]; // треугольник
} geom_fig;
} fig1, fig2;
В общем случае каждый объект типа будет состоять из трех компонентов: , perimetr, type. Компонент type называется меткой активного компонента, так как он используется для указания, какой из компонентов объединения geom_fig является активным в данный момент. Такая структура называется переменной структурой, потому что ее компоненты меняются в зависимости от значения метки активного компонента (значение type ). Отметим, что вместо компоненты type типа int, целесообразно было бы использовать перечисляемый тип. Например, такой
enum figure_chess {CIRCLE, BOX, TRIANGLE};
Константы , , получат значения соответственно равные 0, 1, 2. Переменная type может быть объявлена как имеющая
enum figure_chess type;
В этом случае компилятор С++ предупредит программиста о потенциально ошибочных присваиваниях, таких, например, как ;
В общем случае переменная структуры будет состоять из трех частей: набор общих компонент, метки активного компонента и части с меняющимися компонентами. Общая форма
struct {
ОбщиеКомпоненты; МеткаАктивногоКомпонента;
union {
ОписаниеКомпоненты1;
ОписаниеКомпоненты2;
...................
ОписаниеКомпонентыN;
} ИдентификаторОбъединения;
} ИдентификаторСтруктуры;
Пример 3. Определения helth_record
struct { // общая информация
char name[25]; // имя
int age; // возраст
char sex; // пол
// метка активного компонента(семейное положение)
enum merital_status ins;
// переменная часть
union { // холост
// нет компонент
struct { // состоит в браке
char marriage_date[8];
char spouse_name[25];
int no_children;
} marriage_info;
// разведен */
char date_divorced[8];
} marital_info;
} health_record;
enum marital_status { SINGLE, // холост
MARRIGO, // женат
DIVOREED // разведен
};
Обращаться к компонентам структуры можно при помощи ссылок:
helth_record.nаme helth_record.ins helth_record.marriage_info.marriage_date
Значение указателя на объединение – это адрес расположения элементов объединения.
Объединение (смеси) – объект, который в каждый момент времени содержит один из нескольких элементов различных типов.
Переменные с изменяемой структурой – это переменные
Размер объединения – это объем памяти, занимаемой объединением.
Указатель на объединение – это указатель на расположение элементов объединения в памяти.
Элементы объединения – это множество переменных, определяемых именем переменной объединения.
Цель работы: изучить понятия, оформления и определения объединений, доступ к элементам объединения, указатели на объединения и научиться решать задачи с использованием объединений на языке C++.
При выполнении лабораторной работы для каждого задания требуется написать программу на языке С++, в которой выполнена разработка объединения в соответствии с постановкой задачи, ввод данных элементов объединения, их обработка и вывод на экран в указанном формате. При этом объединение может являться одним из полей структуры. Ввод данных осуществляется с клавиатуры с учетом требований к входным данным, содержащихся в постановке задачи. Ограничениями на входные данные являются максимальный размер строковых данных, диапазоны
Теоретические сведения.
Ознакомьтесь с материалом лекции 17.
Задания к лабораторной работе.
Выполните приведенные ниже задания.
Указания к выполнению работы.
Каждое задание необходимо решить в соответствии с изученными методами объявления и обработки данных объединений в языке С++. В задачах объединение, как правило, является одним из полей
Следует реализовать каждое
Требования к отчету.
Отчет по лабораторной работе должен соответствовать следующей структуре.
Контрольные вопросы
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.