Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Структуры, объединения, перечисления





 

Структуры

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

Термин «структура» в языке Си соответствует двум разным по смыслу понятиям:

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

- структура – это правила формирования структурной переменной, которыми руководствуется компилятор при выделении ей места в ОП и организации доступа к ее полям.

Определение объектов типа структуры производится за два шага:

- декларация структурного типа данных, не приводящая к выделению участка памяти;

- определение структурных переменных с выделением для них памяти.

 

Декларация структурного типа данных

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

struct ID структурного типа {

описание полей

};

Атрибут «ID структурного типа», т.е. ее идентификатор является необязательным и может отсутствовать.

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

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

struct Stud_type {

char Number[10];

char Fio[40];

double S_b;

};

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

struct Stud_type {

char Number[10], Fio[40];

double S_b;

};

Интерпретация объекта типа Stud_type:

Number Fio S_b
     
длина в байтах

 

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

Примеры групповых операций:

- захват и освобождение памяти для объекта;

- запись и чтение данных, хранящихся на внешних носителях как физические и/или логические записи с известной структурой (при работе с файлами).

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

struct Stud_type {

char *Number, *fio;

double S_b;

};

в данном случае, вводя строки Number и fio различной длины, размеры объектов будут также различны.

 

Создание структурных переменных

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

Способ 1. В любом месте программы для декларации структурных переменных, массивов, функций и т.д., используется объявленный в шаблоне структурный тип, например:

struct Stud_type student; - структурная переменная;

Stud_type Stud[100]; - массив структур

Stud_type *p_stud; - указатель на структуру

Stud_type* Fun(Stud_type); - прототип функции с параметром стру­ктур­ного типа, возвращающей указатель на объект структурного типа.

Способ 2: в шаблоне структуры между закрывающейся фигурной скобкой и символом «;» указывают через запятые идентификаторы структурных данных.

Для нашего примера, используя, можно записать:

struct Stud_type {

char Number[10], Fio[40];

double S_b;

} student, Stud[100], *p_stud;

Если дальше в программе не понадобится вводить новые данные объявленного структурного типа, «Stud_type» можно не указывать.

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

Например:

struct Stud_type {

char Number[10], Fio[40];

double S_b;

} student = {“123456”, “Иванов И.И.”, 6.53 };

или:

Stud_Type stud1 = {“123456”, “Иванов И.И.” };

Отметим, что если список инициализации будет короче, то оставшиеся поля структурной переменной будут заполнены нулями.

 

Некоторые особенности:

1) поля структуры, как правило, имеют разный тип кроме функций, файлов и самой этой структуры;

2) поля не могут иметь атрибут, указывающий «класс памяти», данный атрибут можно определить только для всей структуры;

3) идентификаторы (ID), как самой структуры, так и ее полей могут совпадать с ID других объектов программы, т.к. шаблон структуры обладает собственным пространством имен;

4) при наличии в программе функций пользователя шаблон структуры рекомендуется поместить глобально перед определениями всех функций и в этом случае он будет доступен всем функциям.

Элементы структур в общем случае размещаются в памяти последо­ва­тельно с учетом выравнивания начальных адресов.

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

 

Обращение к полям структур производится при помощи составных имен, которые образуются двумя способами:

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

ID_структуры. ID_поля

или

(*указатель_структуры).ID_поля

б) при помощи операции косвенной адресации (->) в виде:

указатель_структуры -> ID_поля

или

(& ID_структуры) ->ID_поля

 

Примеры обращения для объявленного ранее шаблона:

1). Stud_Type s1, s2;

Обратиться к полям элемента объявленной структуры s1:

s1. Number, s1. Fio, s1. S_b; 2). Stud_Type *s1, *s2;

Обратиться к полям элемента объявленной структуры s1:

s1 -> Number, s1 -> Fio, s1 -> S_b;

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

Пусть необходимо содержимое структурной переменной s2 присвоить s1:

Stud_Type s1, s2;

Идентификатор структурной переменной является константным указателем на начало размещения данного объекта в ОП, поэтому, в выражении s1 = s2; допущена ошибка, т.к. в левой части - константа. Правильное присваивание:

memcpy(&s1,&s2,sizeof(Stud_Type));

или

Stud_Type *s1, s2;

s1 = s2;

Участок программы, иллюстрирующий передачу структурных данных в функцию:

struct Spisok {

char Fio[20];

float S_Bal;

};

// Описание прототипов

void Out(Spisok);

void Vvod(int, Spisok *);

void main(void) {

Spisok Stud[50], *sved;

...

for(i=0;i<N;i++)

Vvod(i, &Stud[i]);

puts("\n Spisok Students");

for(i=0;i<N;i++)

Out(Stud[i]);

...

}

 

void Out(Spisok dan) {

printf("\n %20s %4.2f",dan.Fio, dan.S_Bal);

}

 

void Vvod(int nom, Spisok *sved) {

printf("\n Введи сведения %d: ",nom+1);

fflush(stdin);

puts("\n ФИО - ");

gets(sved->Fio);

puts("\n Средний балл - ");

scanf(“%f”, &sved->S_Bal);

}

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

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

Например, в структуре person, содержащей сведения - Ф.И.О., дата рождения, сделать дату рождения внутренней структурой date по отношению к структуре person. Тогда шаблон такой конструкции будет выглядеть так:

struct date {

int day, month, year;

};

struct person {

char fio[40];

struct date f1;

};

Объявляем переменную и указатель на переменные такой структуры:

struct person a, *p;

Инициализируем указатель p адресом переменной а:

p = &a;

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

a. fio a. f1. day a. f1. month a. f1. year

или

p -> fio p -> f1. day p -> f1. month p -> f1. year

Можно в качестве связи с вложенной структурой использовать указатель на нее:

struct date {

int day, month, year;

};

struct person {

char fio[40];

struct date *f1;

};

Тогда обращение к полям будет следующим:

a. fio a. f1 -> day a. f1 -> month a. f1 -> year

или

p -> fio p -> f1 -> day p -> f1 -> month p -> f1 -> year

Использование средства typedef упрощает определение структурных переменных, так как отпадает необходимость при их декларации указывать ключевое слово stuct. Например:

typedef struct person {

char fio[40];

int day, month, year;

} W;

здесь W - созданный пользователем тип данных - «структура с указанными полями» и для нашего примера:

W t1, t2; - декларация двух переменных типа W, а это значит, что можно на такие переменные устанавливать указатели и использовать косвенную адресацию.

Массивы структур

Структурный тип "struct ID_структуры" как правило используют для декларации массивов, элементами которых являются структурные переменные. Это позволяет создавать программы, оперирующие с "примитивными базами данных". Например:

struct person spisok[100]; // spisok - массив структур

Или можно записать так:

struct person {

char fio[40];

int day, month, year;

} spisok[100];

В данном случае обращение к полю, например, day i -той записи может быть выполнено одним из следующих способов:

spisok[i]. day=22; *(spisok+i). day=22; (spisok+i) -> day=22;

 







Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор...

ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между...

ЧТО И КАК ПИСАЛИ О МОДЕ В ЖУРНАЛАХ НАЧАЛА XX ВЕКА Первый номер журнала «Аполлон» за 1909 г. начинался, по сути, с программного заявления редакции журнала...

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





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.