Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
ГЛАВА 13. Структуры, объединения, перечисления
В реальных задачах информация, которую требуется обрабатывать, может иметь достаточно сложную структуру. Для ее адекватного представления используются типы данных, построенные на основе базовых типов данных, массивов и указателей. Языки высокого уровня позволяют программисту определять свои типы данных и правила работы с ними, т.е. типы, определяемые пользователем. В языке Си к ним относятся структуры, объединения и перечисления. Рассмотрим их более подробно.
Структуры Структура – это составной объект языка Си, представляющий собой совокупность логически связанных данных различных типов, объединенных в группу под одним идентификатором. Данные, входящие в эту группу, называют полями. Термин « структура » в языке Си соответствует двум разным по смыслу понятиям: – структура – это обозначение участка оперативной памяти, где располагаются конкретные значения данных; в дальнейшем – это структурная переменная, поля которой располагаются в смежных областях ОП; – структура – это правила формирования структурной переменной, которыми руководствуется компилятор при выделении ей места в ОП и организации доступа к ее полям. Определение объектов типа структуры производится за два шага: – декларация структурного типа данных, не приводящая к выделению участка памяти; – определение структурных переменных объявленного структурного типа с выделением для них памяти.
Декларация структурного типа данных Структурный тип данных задается в виде шаблона, общий формат описания которого следующий: 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 в ОП схематически будет выглядеть следующим образом:
Структурный тип данных удобно применять для групповой обработки логически связанных объектов. Параметрами таких операций являются адрес и размер структуры. Примеры групповых операций: – захват и освобождение памяти для объекта; – запись и чтение данных, хранящихся на внешних носителях как физические и/или логические записи с известной структурой (при работе с файлами). Так как одним из параметров групповой обработки структурных объектов является размер, не рекомендуется декларировать поле структуры указателем на объект переменной размерности, т.к. в данном случае многие операции со структурными данными будут некорректны, например, 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) при наличии в программе функций пользователя шаблон структуры рекомендуется поместить глобально перед определениями всех функций и в этом случае он будет доступен всем функциям. Обращение к полям структур Обращение к полям структур производится путем создания составных имен, которые образуются двумя способами: 1) при помощи операции принадлежности (. ) общий вид которой ID_структуры. ID_поля или ( *указатель_структуры ) . ID_поля 2) при помощи операции косвенной адресации ( –> ) в виде указатель_структуры –> ID_поля или ( & ID_структуры ) –> ID_поля Если в программе созданы объекты объявленного ранее шаблона: Stud_Type s1, *s2; то к полям объекта s1 можно обратиться следующим образом: s1. Number, s1. Fio, s1. S_b; или (& s1) –> Number, (& s1) –> Fio, (& s1) –> S_b; а к полям объекта, адрес которого s2: s2 –> Number, s2 –> Fio, s2 –> S_b; или (*s2). Number, (*s2). Fio, (*s2). S_b;
Вложенные структуры Структуры могут быть вложенными, т.е. поле структуры может быть связующим полем с внутренней структурой, описание которой должно предшествовать по отношению к основному шаблону. Например, в структуре 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
Массивы структур Структурный тип «struct ID_структуры», как правило, используют для декларации массивов, элементами которых являются структурные переменные. Это позволяет создавать программы, оперирующие с простейшими базами данных. Например, массив структур, объявленного ранее типа: struct Person spisok[100]; причем ключевое слово struct можно не писать. Декларацию массива можно выполнить и в описании шаблона следующим образом: struct Рerson { char fio[40]; int day, month, year; } spisok[100]; В данном случае обращение к полю, например, day элемента массива с индексом i может быть выполнено одним из следующих способов: spisok[i].day=22; *(spisok+i).day=22; (spisok+i)–> day=22; Пример. Приведем часть программы, иллюстрирующей создание массива структур и передачу структурных данных в функции: struct Spisok { char Fio[20]; double S_Bal; }; // Описание прототипов функций пользователя void Out(int, Spisok); void In(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(i+1, Stud[i]); ... } // Функция вывода на экран данных одного элемента структуры void Out(int nom, Spisok dan) { printf(" \n %3d – %20s %4.2lf ", nom, dan.Fio, dan.S_Bal); } // Функция ввода данных одного элемента структуры void In (int nom, Spisok *sved) { printf(" \n Введите сведения %d: ", nom+1); fflush(stdin); puts(" \n ФИО – " ); gets(sved–> Fio); puts(" \n Средний балл – " ); scanf(“%lf”, & sved–> S_Bal); }
Популярное: |
Последнее изменение этой страницы: 2016-03-16; Просмотров: 1496; Нарушение авторского права страницы