Создание структурных переменных
Как уже отмечалось, само описание структуры не приводит к выделению под нее места в ОП. Для работы со структурами необходимо создать нужное количество переменных приведенного структурного типа, сделать это можно двумя способами.
Способ 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);
}