Лабораторная работа №8 СТРУКТУРЫ
Цель работы: изучить синтаксис и правила работы со структурами.
Теоретические сведения
При разработке программ важным является выбор эффективного способа представления данных. Во многих случаях недостаточно объявить простую переменную или массив, а нужна более гибкая форма представления данных. Таким элементом может быть структура, которая позволяет включать в себя разные типы данных, а также другие структуры. Приведем пример, в котором использование структуры позволяет эффективно представить данные. Таким примером будет инвентарный перечень книг, в котором для каждой книги необходимо указывать ее наименование, автора и год издания. Причем количество книг может быть разным, но будем полгать, что не более 100. Для хранения информации об одной книге целесообразно использовать структуру, которая задается в языке С с помощью ключевого слова struct, за которым следует ее имя. Само определение структуры, т.е. то, что она будет содержать, записывается в фигурных скобках {}. В данном случае структура будет иметь следующий вид:
struct book {
char title[100]; //наименование книги
char author[100]; //автор
int year; //год издания
};
Такая конструкция задает своего рода шаблон представления данных, но не сам объект, которым можно было бы оперировать подобно переменной или массиву. Для того чтобы объявить переменную для структуры с именем book используется такая запись:
struct book lib; //объявляется переменная типа book
После объявления переменной lib имеется возможность работать со структурой как с единым объектом данных, который имеет три поля: title, author и year. Обращение к тому или иному полю структуры осуществляется через точку: lib.title, lib.author и lib.year. Таким образом, для записи в структуру информации можно использовать следующий фрагмент программы:
printf(“Введите наименование книги: “); scanf(“%s”,lib.title);
printf(“Введите автора книги: “); scanf(“%s”,lib.author);
printf(“Введите год издания книги: “); scanf(“%d”,&lib.year);
После этого в соответствующие поля будет записана введенная с клавиатуры информация и хранится в единой переменной lib. Однако по условиям задачи необходимо осуществлять запись не по одной, а по 100 книгам. В этом случае целесообразно использовать массив структур типа book, который можно задать следующим образом:
struct book lib[100];
В этом случае программу ввода и хранения информации по книгам можно записать в виде:
Листинг 1. Инвентарный перечень книг.
#include <stdio.h> struct book {
char title[100]; //наименование книги
char author[100]; //автор int year; //год издания
};
int main()
{
int cnt_book = 0, ch; struct book lib[100]; do
{
printf(“Введите наименование книги: “); scanf(“%s”,lib[cnt_book].title); printf(“Введите автора книги: “); scanf(“%s”,lib[cnt_book].author); printf(“Введите год издания книги: “); scanf(“%d”,&lib.year);
printf(“Нажмите q для завершения ввода: ”); cnt_book++;
}
while(scanf(“%d”,ch) == 1 && cnt_book < 100); return 0;
}
Данный пример показывает удобство хранения информации по книгам. Тот же алгоритм в общем случае можно реализовать и без структуры, но тогда пришлось бы использовать два двумерных массива символов и один одномерный массив для хранения года издания. Несмотря на то, что формально такая запись была бы корректной с точки зрения языка С, но менее удобна в обращении. Графически массив структур можно представить в виде таблицы, в которой роль столбцов играют поля, а роль строк элементы массива структур.
|
lib[0]
|
|
|
lib[99]
Структуры можно автоматически инициализировать при их объявлении подобно массивам, используя следующий синтаксис:
struct bool lib = { “Евгений Онегин”, “Пушкин А.С.”, 1995
};
При выполнении данного фрагмента программы в переменные структуры title, author и year будет записана соответственно информация: “Евгений Онегин”, “Пушкин А.С.”, 1995. Здесь следует обратить внимание, что последовательность данных при инициализации должна соответствовать последовательности полей в структуре. Это накладывает определенные ограничения, т.к. при инициализации необходимо помнить последовательность полей в структуре. Стандарт C99 допускает более гибкий механизм инициализации полей структуры:
struct book lib = {.year = 1995,
.author = “Пушкин А.С.”,
.title = “Евгений Онегин” };
или
struct book lib = {.year = 1995,
.title = “Евгений Онегин” };
или
struct book lib = {.author = “Пушкин А.С.”,
.title = “Евгений Онегин”, 1995 };
В первом и во втором примерах при инициализации указываются наименования полей через точку. При этом их порядок и число не имеет значения. В третьем примере первые два поля указаны через имена, а последнее
инициализируется по порядковому номеру – третьему, который соответствует полю year.
В некоторых случаях имеет смысл создавать структуры, которые содержат в себе другие (вложенные) структуры. Например, при создании простого банка данных о сотрудниках предприятия целесообразно ввести, по крайней мере, две структуры. Одна из них будет содержать информацию о фамилии, имени и отчестве сотрудника, а вторая будет включать в себя первую с добавлением полей о профессии и возрасте:
struct tag_fio { char last[100]; char first[100]; char otch[100];
};
struct tag_people {
struct tag_fio fio; //вложенная структура
char job[100]; int old;
};
Рассмотрим способ инициализации и доступ к полям структуры people на следующем примере.
Листинг 2. Работа с вложенными структурами.
int main()
{
struct people man = {
{“Иванов”, “Иван”, “Иванович”}, “Электрик”,
50 };
printf(“Ф.И.О.:%s %s %s\n”,man.fio.last,man.fio.first,
man.fio.otch);
printf(“Профессия: %s \n”,man.job); printf(“Возраст: %d\n”,man.old); return 0;
}
В данном примере показано, что для инициализации структуры внутри другой структуры следует использовать дополнительные фигурные скобки, в которых содержится информация для инициализации полей фамилии, имени и отчества сотрудника. Для того чтобы получить доступ к полям вложенной структуры выполняется сначала обращение к ней по имени man.fio, а затем к ее полям: man.fio.last, man.fio.first и man.fio.otch. Используя данное правило, можно создавать многоуровневые вложения для эффективного хранения и извлечения данных.
Структуры, как и обычные типы данных, можно передавать функции в качестве аргумента. Следующий пример демонстрирует работу функции отображения полей структуры на экран.
Листинг 3. Передача структур через аргументы функции.
#include <stdio.h> struct tag_people {
char name[100]; char job[100]; int old;
};
void show_struct(struct tag_people man); int main()
{
struct tag_people person = {“Иванов”,”Электрик”,30}; show_struct(person);
return 0;
}
void show_struct(struct tag_people man)
{
printf(“Имя: %s\n”,man.name); printf(“Профессия: %s\n”,man.job); printf(“Возраст: %d\n”,man.old);
}
В приведенном примере используется функция с именем show_struct, которая имеет тип аргумента struct tag_people и переменную-структуру man. При передаче структуры функции создается ее копия, которая доступная в теле функции show_struct под именем man. Следовательно, любые изменения полей структуры с именем man никак не повлияют на содержание структуры с именем person. Вместе с тем иногда необходимо выполнять изменение полей структуры функции и возвращать измененные данные вызывающей программе. Для этого можно задать функцию, которая будет возвращать структуру, как показано в листинге 4.
Листинг 4. Функции, принимающие и возвращающие струткуру.
#include <stdio.h> struct tag_people {
char name[100]; char job[100]; int old;
};
void show_struct(struct tag_people man); struct tag_people get_struct();
int main()
{
struct tag_people person; person = get_struct(); show_struct(person); return 0;
}
void show_struct(struct tag_people man)
{
printf(“Имя: %s\n”,man.name); printf(“Профессия: %s\n”,man.job); printf(“Возраст: %d\n”,man.old);
}
struct tag_people get_struct()
{
struct tag_people man; scanf(“%s”,man.name);
scanf(“%s”,man.job);
scanf(“%d”,man.old); return man;
}
В данном примере используется функция get_struct(), которая инициализирует структуру с именем man, запрашивает у пользователя ввод значений ее полей и возвращает введенную информацию главной программе. В результате выполнения оператора присваивания структуры man структуре person, происходит копирование информации соответствующих полей и автоматическое удаление структуры man.
Функциям в качестве аргумента можно также передавать массивы структур. Для этого используется следующее определение:
void show_struct(struct people mans[], int size);
Здесь size – число элементов массива, которое необходимо для корректного считывания информации массива mans. Следующий пример показывает принцип работы с массивами структур.
Листинг 5. Передача массив структур функции.
#include <stdio.h> #define N 2
struct tag_people { char name[100]; char job[100]; int old;
};
void show_struct(struct people mans[], int size); int main()
{
struct people persons[N] = {
{ “Иванов”, «Электрик», 35 },
{ “Петров”, «Преподаватель», 50 },
};
show_struct(persons, N);
}
void show_struct(struct people mans[], int size)
{
for(int i = 0;i < size;i++) { printf(“Имя: %s\n”,mans[i].name);
printf(“Профессия: %s\n”,mans[i].job); printf(“Возраст: %d\n”,mans[i].old);
}
}
При передаче аргумента persons выполняется копирование информации в массив mans и указывается дополнительный параметр size, для определения числа элементов массива mans. Затем в функции show_struct() реализуется цикл, в котором выполняется отображение информации массива структуры на экран монитора.
Задание на лабораторную работу
1. Написать программу работы со структурой в соответствии с номером своего варианта.
2. Написать программу работы с массивом структур в соответствии с номером своего варианта.
3. Сделать выводы по полученным результатам работы программы.
Варианты заданий
Вариант | Задание со структурой | Задание с массивом структур |
Написать программу ввода домашнего адреса в структуру | Написать программу поиска книги по году издания в массиве структур | |
Написать программу ввода информации по сотруднику (Ф.И.О.,возраст,должность, кафедра) | Написать программу удаления книги из массива структур с введенным именем автора | |
Написать программу ввода информации по студенту (Ф.И.О.,группа,факультет,курс) | Написать программу поиска числа книг с заданным годом издания | |
Написать программу копирования одной структуры (с информацией о книге) в другую | Написать программу сортировки книг в массиве структур по убыванию года издания | |
Написать функцию сравнения двух структур (шаблон структуры задается произвольно) | Написать программу добавления новой книги в начало массива структур. | |
Написать функцию, принимающую значения полей структуры и возвращающую ее заполненную | Написать программу поиска сотрудников с указанным именем в массиве структур сотрудников | |
Написать программу ввода адреса учреждения (Название, город, улица, дом, подъезд) | Написать программу сортировки студентов по возрастанию номера их группы | |
Написать программу ввода информации о маршрутном такси (номер, стоимость,вид транспорта,…) | Написать программу удаления информации о сотруднике с указанным возрастом |
Написать программу ввода информации по книге (автор, год изд., число стр., цена, название) | Написать программу сортировки книг по возрастанию их цен | |
Написать программу ввода информации о продукте | Написать программу удаления учреждений с указанным названием | |
(наименование, цена, магазин, вес, | из массива структур учреждений | |
габариты) | ||
Написать программу ввода информации о питомце (порода,имя, возраст, вес,владелец) | Написать программу сортировки студентов по убыванию номера их группы | |
Написать программу ввода информации по сотруднику (фамилия,зарплата,должность, выработка часов) | Написать программу удаления информации о сотруднике с указанной зарплатой | |
Написать программу ввода адреса магазина (страна,название, город, улица, дом, подъезд) | Написать программу поиска машины с заданным годом выпуска | |
Написать функцию сравнения двух структур (шаблон структуры задается произвольно) | Написать программу сортировки книг по убыванию их цен | |
Написать программу ввода информации общественного транспорта (номер,количество остановок, стоимость,маршрут,вид транспорта) | Написать программу удаления информации о машине с указанной моделью | |
Написать программу копирования одной структуры (с информацией о продукте) в другую | Написать программу добавления нового мобильного телефона в начало массива структур. | |
Написать функцию, принимающую значения полей структуры(книги) и возвращающую ее заполненную | Написать программу сортировки сотрудников по убыванию их возраста | |
Написать программу ввода информации о машине (марка,модель, год выпуска, пробег,владелец) | Написать программу сортировки машин по убыванию их Года выпуска | |
Написать программу копирования одной структуры (с информацией о машине) в другую | Написать программу добавления нового сотрудника в начало массива структур. | |
Написать программу ввода информации о мобильном телефоне (марка,модель, год выпуска, операционная система,память) | Написать программу сортировки сотрудников по возрастанию их возраста |
Содержание отчета
5. Титульный лист с названием лабораторной работы, номером своего варианта, фамилией студента и группы.
6. Текст программ.
7. Результаты действия программ.
8. Выводы по полученным результатам работы программ.
Контрольные вопросы
7. Запишите структуру для хранения имени, возраста и места работы сотрудника.
8. Как задаются переменные на структуры?
9. Как задаются массивы структур?
10.Запишите инициализацию структуры хранения книг.
11.Каким образом передаются структуры функциям?
12.Можно передавать функции массив структур?