Лабораторная работа №10 Тема: Структурный тип данных в языке С++ Цель: Изучение алгоритмов обработки объектов структурного типа данных и способов их реализации в языке С++. 1. 2. 3. 4. Задания для самостоятельного выполнения. Методические указания. Пример выполнения задания. Рейтинговый контроль. 1 1. Задания для самостоятельного выполнения Вариант №1 Описать структуру с именем STUDENT, содержащую следующие поля: Фамилия и инициалы; Номер группы; Успеваемость (массив из 5 элементов). Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 10 структур типа STUDENT; записи должны быть упорядочены по возрастанию номера группы; Вывод фамилий и номеров групп тех студентов, чей средний балл больше 4.0. Если таких студентов нет, вывести соответствующее сообщение. Вариант №2 Описать структуру с именем STUDENT, содержащую следующие поля: Фамилия и инициалы; Номер группы; Успеваемость (массив из 5 элементов). Написать программу, выполняющую следующие действия: - Ввод с клавиатуры данных в массив, состоящий из 10 структур типа STUDENT; записи должны быть упорядочены по возрастанию среднего балла. - Вывод фамилий и номеров групп студентов, имеющих оценки 4 и 5. - Если таких студентов нет, вывести соответствующее сообщение. Вариант №3 Описать структуру с именем STUDENT, содержащую следующие поля: Фамилия и инициалы; Номер группы; Успеваемость (массив из 5 элементов). Написать программу, выполняющую следующие действия: - Ввод с клавиатуры данных в массив, состоящий из 10 структур типа STUDENT; записи должны быть упорядочены по алфавиту. - Вывод фамилий и номеров групп студентов, имеющих хотя бы одну 2. - Если таких студентов нет, вывести соответствующее сообщение. Вариант №4 Описать структуру с именем AEROFLOT, содержащую следующие поля: Название пункта назначения рейса; Номер рейса; Тип самолёта. Написать программу, выполняющую следующие действия: - Ввод с клавиатуры данных в массив, состоящий из 7 структур типа AEROFLOT; записи должны быть упорядочены по возрастанию номера рейса; - Вывод номеров рейсов и типов самолётов, вылетающих в пункт назначения, название которого совпало с названием, введённым с клавиатуры. 2 - Если таких рейсов нет, вывести соответствующие сообщение. Вариант №5 Описать структуру с именем AEROFLOT, содержащую следующие поля: Название пункта назначения рейса; Номер рейса; Тип самолёта. Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 7 структур типа AEROFLOT; записи должны быть упорядочены в алфавитном порядке по названиям пунктов назначения; Вывод пунктов назначения и номеров рейсов, обслуживаемых самолётом, тип которого введён с клавиатуры. Если таких рейсов нет, вывести соответствующие сообщение. Вариант №6 Описать структуру с именем NOTE содержащую следующие поля: Фамилия, имя; Номер телефона; Дата рождения (массив из трёх чисел). Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 8 структур типа NOTE, записи должны быть упорядочены по датам рождения; Вывод информации о тех людях, чьи дни рождения приходятся на месяц, значение которого введено с клавиатуры. Если таких нет, вывести соответствующие сообщение. Вариант №7 Описать структуру с именем NOTE содержащую следующие поля: Фамилия, имя; Номер телефона; Дата рождения (структура с полями день, месц, год). Написать программу, выполняющую следующие действия: - Ввод с клавиатуры данных в массив, состоящий из 8 структур типа NOTE, записи должны быть размещены по алфавиту; - Вывод информации о человеке, номер телефона которого введён с клавиатуры; - Если такого нет, вывести соответствующие сообщение. Вариант №8 Описать структуру с именем NOTE содержащую следующие поля: Фамилия, имя; Номер телефона; Дата рождения (структура с полями день, месц, год). Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 8 структур типа NOTE, записи должны быть упорядочены по первым цифрам телефона; 3 - Вывод информации о человеке, чья фамилия введена с клавиатуры; Если такого нет, вывести соответствующие сообщение. Вариант №9 Описать структуру с именем ZNAK содержащую следующие поля: Фамилия, имя; Знак Зодиака; Дата рождения (структура с полями день, месц, год). Написать программу, выполняющую следующие действия: - Ввод с клавиатуры данных в массив, состоящий из 8 структур типа ZNAK, записи должны быть упорядочены по датам рождения; - Вывод информации о человеке, чья фамилия введена с клавиатуры; - Если такого нет, вывести соответствующие сообщение. Вариант №10 Описать структуру с именем ZNAK содержащую следующие поля: Фамилия, имя; Знак Зодиака; Дата рождения (структура с полями день, месц, год). Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 8 структур типа ZNAK, записи должны быть упорядочены по знакам зодиака; Вывод информации о людях, родившихся под знаком, введённом с клавиатуры. Если такого нет, вывести соответствующие сообщение. Вариант №11 Ввести несколько структур типа «Зачетка студента» с полями {Фамилия студента Номер зачетки Массив из 4 оценок } Написать программу, выполняющую следующие действия: - Сортировка структур по фамилии или среднему баллу - Удаление всех зачеток троечников Вариант №12 Ввести несколько структур типа «Товары на складе» с полями { название товара закупочная цена товарная наценка } Написать программу, выполняющую следующие действия: - Уценяет на 20% все товары, которые дороже заданной цены. 4 - Выводит товары в порядке возрастания розничной цены. Вариант №13 Ввести несколько структур с полями день месяц год Написать программу, выполняющую следующие действия: - Сортирует структуры по описываемой дате - Выводит на экран те 2 из них, которые наиболее близки друг к другу по описываемой дате. Вариант №14 Дана структура "поезд" с полями: Наименование маршрута Время отправления Время прибытия Длина маршрута Ввести несколько структур и отсортировать поезда а) по времени движения; б) по средней скорости движения; Вывести наименование маршрутов, время в пути для которых меньше заданного времени Вариант №15 Ввести несколько структур с полями день месяц год Написать программу, выполняющую следующие действия: - Сортирует структуры по описываемой дате - Выводит на экран те структуры , которые описывают воскресенье Вариант №16 Ввести несколько структур "Зачетка студента" с полями: Фамилия студента Номер зачетки Массив структур "Предмет" Структура "Предмет" имеет поля: Фамилия преподавателя Название предмета Оценка Написать программу, выполняющую следующие действия: - Сортирует студентов по среднему баллу. 5 - Находит предмет, по которому все студенты успевают (не имеют двоек) Вариант №17 Ввести несколько структур "Зачетка студента" с полями: Фамилия студента Номер зачетки Массив структур "Предмет" Структура "Предмет" имеет поля: Фамилия преподавателя Название предмета Оценка Написать программу, выполняющую следующие действия: - Выводит на экран Фамилии преподавателей, не ставивших "3". - Сортирует структуры по номеру зачетки или фамилии Вариант №18 Ввести несколько структур типа «Товары на продуктовом складе» с полями { Название товара Стоимость товара Дата производства товара Срок годности товара } Написать программу, выполняющую следующие действия: - Удаляет все структруры с истекшим сроком годности - Сортирует структуры в порядке стоимости или наименования Вариант №19 Ввести несколько структур "Зачетка студента" с полями: Фамилия студента Номер зачетки Массив структур "Предмет" Структура "Предмет" имеет поля: Фамилия преподавателя Название предмета Оценка Написать программу, выполняющую следующие действия: - Удаляет всех неуспевающих студентов (у которых есть двойка хотя по одному из предметов) - Сортирует структуры по фамилии или номеру зачетки Вариант №20 Ввести несколько структур "Зачетка студента" с полями: 6 Фамилия студента Номер зачетки Размер стипендии Массив структур "Предмет" Структура "Предмет" имеет поля: Фамилия преподавателя Название предмета Оценка Написать программу, выполняющую следующие действия: - устанавливает стипендии для всех студентов, которые учатся на 4 и 5 - сортирует структуры в порядке роста среднего балла 2. Методические указания Для выполнения данной лабораторной работы необходимо изучить теоретический материал по теме «Структуры». Структура как и массив относятся к составным данным, т.е. это объект, состоящий из нескольких элементов (в Паскале – запись, состоящая из полей). В простейшем случае элементами структуры являются объекты типа int, float, char… В более сложных – можно использовать объекты любого типа, в том числе массивы, структуры. 1. Объявление структурного шаблона (структурного типа). Информация о книге: Автор Название Год Цена struct kniga /* имя шаблона */ { char avtor[20]; char nazv[60]; int god; float cena; }; или #define KNIGA struct kniga Шаблон может быть локальным (внутри функции) или глобальным (вне функции). Описание шаблона не вызывает выделения памяти. Это - аналог описания типа. 2. Определение структурных переменных Определим структурную переменную kn1: - Ссылка на шаблон: struct kniga kn1; или KNIGA kn1; struct kniga - тип переменной; 7 kn1 – имя переменной; struct kniga kn1, kn2, *uk_kniga; kn1, kn2 - две переменных; *uk_kniga – указатель на структуру kniga - Определение структурной переменной без ссылки на шаблон: struct { int a; float b; }z1, z2; z1,z2 – две переменных типа struct; - Использование typedef typedef struct { … }KNIGA; KNIGA kn1; 3. Инициализация Инициализация возможна только для внешних и статистических структур. Принадлежность к внешнему типу определяется местом объявления структурной переменной, а не шаблона. static struct kniga kn1={“Иванов А.И.”, ”физика”, 1983, 1.75} ; 4. Доступ к элементам структуры Аналогично Паскалю используются составные имена. Составное имя <имя переменной>.<имя элемента> struct kniga kn1; kn1.avtor – имя символьного массива[20] – адрес kn1.nazv – имя символьного массива[60] kn1.god – имя переменной типа int kn.cena – имя переменной типа float, &kn1.cena – адрес Эти имена могут быть использованы так же, как и обычные имена переменных: kn1.avtor[5]=‘a‘; scanf(“% f“,&kn1.cena); kn1.god =1988 ; *(kn1.avtor+1)=‘p‘ ; gets(kn1.nazv); 5. Массивы структур 8 struct kniga kns[3] – массив из трех структур kns[0].avtor – указатель на массив kns[1].god - третий элемент второй структуры kns[2].nazv[0] номер элемента массива всегда указывается после имени. 0 Автор 1 название 2 год 3 цена 0 1 2 6. Вложенные структуры Элементом структуры может быть другая структура КНИГА АВТОР ИМЯ НАЗВАНИЕ ГОД ОТЧЕСТВО АВТОР ФАМИЛИЯ struct avtor { char im[10]; char ot[15]; char fam[15]; }; struct kninga1 { struct avtor avt; /* Вложенная структура */ char nazv[60]; int god; float cena; }; 7. Определение переменной и инициализация struct avtor avt1; struct kniga1 kn_89 = / * инициализация только внешних или статических * / / * переменных */ { {“Иван “, ”Иванович”, “ Иванов “}, ”физика“, 1989, 1.75 9 }; Доступ: kn_89.avt.fam[1]=‘p‘; Иранов 8. Указатели на структуры Целесообразно использование указателей на структуры по трем причинам: так же, как и указатели на массивы, они легче в использовании, чем сами массивы; многие удобные представления данных являются структурами, содержащими указатели к другим структурам. struсt avtor *ukavt; struсt kniga1 *ukknig; /* объявление двух указателей на структуры * / Все операции с указателями, справедливые для обычных переменных, справедливы и для структурных переменных. Можно использовать операции: ukavt=&avt1; ukknig=&kn-89; *ukavt avt1 Имя структуры - это не адрес! Указатели и массивы структур struct kniga1 kni[100]; ukknig=kni; ukknig=&kni[0]; ukknig=kni+1; ukknig=&kni[1]; Прибавление “1“ к указателю увеличивает его значение (адрес) на число байтов, которое занимает соответствующий тип. ukknig++; ukknig=&kni[2]; *ukknig=kni[2]; Операции над структурами - Присваивание: struсt kniga kn1,kn2; kn2=kn1; - Сравнение структур - осуществляют специальные подпрограммы. - Доступ к элементу структуры выполняется при помощи указателя: struct avtor *ukavt, avt1; ukavt – указатель на структуру avt1 – переменная типа структуры ukavt=&avt1; /* указатель ссылается на avt1*/ avt1.im[0]=‘a‘; Имя структуры - это не адрес Как с помощью указателя ukavt получить доступ к этому же элементу ? 10 Существует два способа: 1. Операция присоединения ukavt–>im[0]= 'a'; Смысл новой операции –>: avt1.im[0] и ukavt=&avt1; Cтруктурный указатель, за которым следует операция –>, работает так же, как имя структуры с последующей операцией “.“. ( нельзя записать ukavt.im[0] т.к. ukavt – не является именем структуры). Важно отметить, что ukavt – указатель, а ukavt–>im[0] - элемент структуры, на которую делается ссылка и имеет тип char. 2. Другой способ получить доступ к элементу структуры с помощью составного имени. Составное имя (*ukavt ).im[0]= 'a'; Круглые скобки необходимы, т.к. операция “.” имеет более высокий приоритет, чем * Содержимое по адресу ukavt: ukavt=&avt1; *ukavt=*(&avt1); avt1 “Дыры” могут возникать на стыке соседних элементов структуры из-за выравнивания границ памяти. | ‘a‘ | ? | 1 | 2 | char int 8. Передача информации о структурах функциям Саму структуру можно использовать в качестве формальных параметров функции. 1. Можно передавать в качестве фактических параметров элемент структуры или его адрес. struct pr { int a; float b; }; int ab ( int a , float *b ) { *b=2.5*(float)a; return (2*a); } 11 void main() { struct pr pr1; scanf(“%d“,&pr1.a); /* адрес элемента */ printf(“результат: %db=%f\n“,ab(pr1.a,&pr1.b),pr1.b); } 2. Можно использовать адрес структуры в качестве фактического параметра. Объявим шаблон и переменные одновременно в задаче определения остатка от деления целых чисел. struct sab { int a,b; }pr1={21,3}; /* int по умолчанию */ ab1(struct sab *prim) / * указатель на структуру pr1 */ { return (prim->a%prim->b); /* остаток от деления */ } void main() { printf(“остаток=%d“,ab1(&pr1)); } 3. Можно использовать имя массива структур в качестве фактического параметра (то есть адрес первого элемента массива). struct pr { int a; float b; }; /* Глобальный шаблон */ void main() /*найти сумму всех элементов*/ структуры { /*в массиве структур 10 записей*/ int i; float ab2(struct pr *prim); /*прототип функции*/ struct pr pr2[10]; for(i=0;i<10;i++) scanf(“%d %f”,&pr2[i].a,&pr2[i].b); printf(“сумма=%f“,ab2(pr2)); /* pr2 – имя массива структур, адрес первой структуры. */ } float ab2(struct pr *prim) { 12 int i; float sum=0; for(i=0;i<10;i++,prim++)sum+=prim->a+prim->b; return (sum); } Данная лабораторная работа предусматривает в качестве контроля отчет в печатном виде и его защита Отчет должен включать в себя: 1. 2. 3. 4. Текст задания Блок – схему Программный код с комментариями Примеры рез-та работы программы. 3. Пример выполнения задания. Описать структуру с именем NOTE содержащую следующие поля: Фамилия, имя; Номер телефона; Дата рождения (Вложенная структура с тремя полями: день, месяц, год). Написать программу, выполняющую следующие действия: Ввод с клавиатуры данных в массив, состоящий из 8 структур типа NOTE, записи должны быть размещены по алфавиту; Вывод информации о человеке, номер телефона которого введён с клавиатуры; Если такого нет, вывести соответствующие сообщение. #include<iostream> #include<string.h> #include<stdlib.h> #include<stdio.h> #include <windows.h> using namespace std; main() { SetConsoleCP(1251); SetConsoleOutputCP(1251); const int n=5; struct Date { int day, month, year; } ; struct NOTE {char fn[30]; int no; Date bd; }; int j,i,num; 13 bool bFound=false; char c; NOTE box[n], tmp; for(i=0;i<n;i++) { cin.sync(); cout<<"Введиде фамилию, имя"<<endl; cin.getline(box[i].fn, 30); cout<<"Введите номер телефона"<<endl; cin>>box[i].no; cout<<"Введите дату рождения"<<endl; cout<<"число"<<endl;cin>>box[i].bd.day; cout<<"месяц"<<endl;cin>>box[i].bd.month; cout<<"год"<<endl;cin>>box[i].bd.year; } cout<<"Введите номер телефона для поиска"<<endl; cin>>num; cout<<"Список, упорядоченный по фамилии:"<<endl; for(i=n-1; i>0 ; i--) for(j=0; j<i ; j++) if(strcmp( box[ j ].fn, box[ j+1 ].fn )>0) { tmp=box[ j ]; box[ j ]=box[ j+1 ]; box[ j+1 ]=tmp;} for(i=0;i<n;i++) { cout<<box[i].fn<<endl;cout<<box[i].no<<endl; cout<<box[i].bd.day<<endl; cout<<box[i].bd.month<<endl; cout<<box[i].bd.year<<endl; } cout<<"Результаты поиска по телефону"<<endl; for(i=n-1;i>=0;i--) if(box[i].no==num) {cout<<box[i].fn<<endl; cout<<box[i].no<<endl; cout<<box[i].bd.day<<endl; cout<<box[i].bd.month<<endl; cout<<box[i].bd.year<<endl; bFound=true; } if (!bFuond) cout<<"Нет записей с таким телефоном"; system(“pause”); return 0; } 14 Начало c='#'; q=8 i=0; i<n Ввод: box[i].fn box[i].no, box[i].bd.year, box[i].bd.month, box[i].bd.year, i++ i=n-1; i>0 j=0; j<i - strcmp( box[ j ].fn, box[ j+1 ].fn )>0 + tmp=box[ j ]; box[ j ]=box[ j+1 ]; box[ j+1 ]=tmp; j++ i-- A 15 A i=0; i<n Вывод: box[i].fn box[i].no, box[i].bd.day box[i].bd.month, box1[i].bd.year, i++ i=0; i<n bFound=false e - + box[i].no==num bFound=true Вывод: box[i].fn box[i].no, box[i].bd.day, box[i].bd.month, box1[i].bd.year, i++ - !bFound + Вывод: «Таких нет» Конец 16