Добавил:
ПОИТ 2016-2020 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
38
Добавлен:
29.04.2018
Размер:
223.78 Кб
Скачать

Типы данных, определяемые пользователем

Это

– структуры (structure),

– объединения (union),

– перечисления (enumeration),

– битовые поля (bit fields),

– создание нового имени (псевдонима) с помощью оператора typedef для уже существующего типа.

15. Структуры

Определение структуры

Структура – это совокупность логически связанных данных различного типа, объединенных под одним идентификатором. Данные называются полями.

Структуры полезны, когда надо объединить несколько переменных с разными типами под одним именем. Это делает программу более компактной и гибкой для внесения изменений. Также структуры незаменимы, когда надо сгруппировать некоторые данные, например, запись из базы данных или контакт из книги адресов.

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

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

Тип структуры определяется записью вида:

struct  имя-структуры { список определений };

где имя_структуры является идентификатором.

В приведенном ниже примере идентификатор student описывается как имя структуры:

struct student

{ char *name;

int id, age;

char pol;

} ;

Имя используется для последующего объявления структур данного вида в форме:

struct имя_структуры список-идентификаторов;

Пример: структурированные переменные: struct student st1, st2;

Массив структур: student mas_stud[10];

Указатель на структуру: student *pstud;

Во всех случаях использования структурированной переменной, кроме самого определения структуры слово struct можно опускать, то есть используется только имя структурной переменной.

В структуре обязательно должен быть указан хотя бы один компонент (поле).

Второй способ определения структур, когда идентификаторы перечисляются после описания полей.

Пример:

struct {

double x, y;

} s1, s2, sm[9];

Переменные s1, s2 определяются как структуры, каждая из которых состоит из двух компонент х и у. Переменная sm определяется, как массив из девяти структур.

struct { int year;

char month, day;

} d1, d2;

Каждая из двух переменных d1, d2 состоит из трех компонентов: year, moth,  day. Если объявление структуры не содержит ее имени, то переменные структурного типа могут быть объявлены только в описании структуры, а не с помощью их отдельного объявления.

Использование имени структуры возможно для описания рекурсивных структур. Пример:

struct node

{ int data; node *next; } st1;

Структура node является рекурсивной, т.к. она используется в своем собственном описании. Структуры не могут быть прямо рекурсивными, т.е. структура node не может содержать компоненту, являющуюся структурой node, но любая структура может иметь компоненту, являющуюся указателем на свой тип, как и сделано в приведенном примере.

Структуры имеют следующие свойства:

  • поля структуры могут иметь разный тип;

  • полями структуры могут быть функции (С++);

  • идентификаторы полей структуры могут совпадать с другими идентификаторами программы;

  • структура может быть аргументом и результатом функции

struct man *create() { ... }

void f(struct man *q) { ... }

  • если есть имя, то слово struct можно опускать (С++)

Инициализация структур и доступ к компонентам

Структуры могут быть инициализированы списками значений элементов, заключенных в фигурные скобки и перечисленных через запятую, как и массивы:

struct student

{ char *name;

int id, age;

char pol;

} ;

struct student st1 = {“Петров”, //нач.значение name

1, //нач.значение id

20, //нач.значение age

М’ //нач.значение pol } ;

В том случае, если начальные значения членов структуры известны, можно присвоить их при определении переменной. Если мы создаем только одну переменную структурного типа, можно инициализировать ее как часть определения структуры:

struct CD

{

сhar name [20];

сhar description[40];

char category[12];

float cost;

int number;

} disc = {"Лучшие песни", "Тини Тим", "поп-музыка", 12.50, 12};

В этих инструкциях мы создали структуру CD, определили переменную disc и присвоили начальные значения всем пяти членам структуры.

Доступ к компонентам структуры осуществляется при помощи составных имен двумя способами. Во-первых, с использованием операции принадлежности (.) в виде:

идентификатор_структуры.идентификатор_поля

(*указатель_структуры).идентификатор_поля

Например:

st1.name = “Сидоров”;

st2.id = st1.id;

st1_node.data = st1.age;

Второй способ – при помощи операции косвенной адресации –> (стрелка, минус-больше), которая понимается как выделение элемента в структурированной переменной, адресуемой указателем. Она также называется операцией непрямого доступа:

указатель_структуры->идентификатор_поля

(&идентификатор_структуры)->идентификатор_поля

Операндами здесь является указатель на структуру и элемент структуры.

struct student *pA, A;

pA = &A;

pA > age; // эквивалентно (*pA).age

Работа со структурами поддерживается средствами Intellisense. По мере ввода операции выбора члена структуры вслед за именем структурированной переменной редактор показывает окно со списком всех членов данной структуры.

Указатель на структуру

как формальный параметр

Объекты типа структур можно передавать как параметры функции и возвращать из функции в качестве результата.

Пусть имеется структура:

Фрагмент ниже содержит указатель на структуру man *p в качестве формального параметра, а &A и &X[i] в основной программе – фактические параметры.

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

Указатель на структуру

как результат функции

(&p[i]) - результат

Допустимыми операциями, которые могут быть выполнены со структурами, являются следующие: операция присваивания одной структуры другой структуре того же типа; операция взятия адреса (&) структуры; операция доступа к элементам структуры и операция sizeof для определения размера структуры. Остальные операции, такие как сравнение (== и !=), не определены.

Пример. Информация о студентах содержит фамилии, имена и оценки. В программе вводятся данные и определяется средний балл. Вывод результатов осуществляется в порядке возрастания средних баллов.

Вложенные структуры

Структуры могут быть вложенными, т.е. поле структуры может быть связующим полем с внутренней структурой, описание которой должно предшествовать по отношению к основной структуре:

struct date

{ int day, month, year; };

struct student

{ char *name; date birth_day; };

student A, *pA;

………………………………

Обращение к полям структуры:

birth_day.day = 12;

pA > birth_day.day = 20;

struct puple

{ char name; date *birth_day; };

puple B, *pB;

…………………….

Обращение к полям структуры:

birth_day>day = 24;

pB > birth_day>day = 10;

Cоздание псевдонима с помощью typedef

typedef - позволяет определить производный тип данных и использовать его аналогично базовым

Пример доступа к полям структуры с использованием операции принадлежности (.):

Пример доступа к элементам структуры при помощи операции косвенной адресации –> 

Соседние файлы в папке Лекции