Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование 3.docx
Скачиваний:
9
Добавлен:
17.11.2019
Размер:
265.13 Кб
Скачать

Лабораторная работа № 11 классы. Класс динамического массива структур.

  1. ЦЕЛЬ И ЗАДАЧИ РАБОТЫ

Целью работы является приобретение студентами навыков работы с классами динамического массива структур.

Задачами работы являются:

  • написание программы на языке C++ с использованием класса динамического массивов структур, конструктора и деструктора и обработки файловой информации;

  • реализация меню программы;

  • осуществление процедуры поиска необходимых данных в классе массивов структур, добавления и удаления записей и вывод результатов на экран и в файл;

  • тестирование работоспособности программы для различных исходных данных.

  1. КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

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

автоматической инициализации создаваемых объектов. Для каждого вновь создаваемого объекта необходимо было вызвать функцию типа set (как для класса Date), либо явным образом присваивать значения данным объекта. Однако для инициализации объектов класса в его определение можно явно включить специальную компонентную функцию, называемую конструктором. Формат определения конструктора следующий имя_класса(список_форм_параметров):

Date (int dO = 0, int mO =0, int yO =0)

{

d = dO;

m = mO; y = y0;

}

Конструктор выделяет память для объекта и инициализирует данные-члены класса. Конструктор имеет ряд особенностей. Для конструктора не определяется тип возвращаемого значения. Даже тип void не допустим. Указатель на конструктор не может быть определен и, соответственно, нельзя получить адрес конструктора.

Конструктор всегда существует для любого класса, причем, если он не определен явно, он создается автоматически. По умолчанию создается конструктор без параметров и конструктор копирования. Если конструктор описан явно, то конструктор по умолчанию не создается. По умолчанию конструкторы создаются общедоступными (public).

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

Такую возможность обеспечивает специальный компонент класса - деструктор класса. Его формат:

-имякласса 0 { операторы тела деструктора };

Имя деструктора совпадает с именем его класса, но предваряется символом (тильда).

Деструктор не имеет параметров и возвращаемого значения. Вызов деструктора выполняется не явно (автоматически), как только объект класса уничтожается. Например, при выходе за область определения или при вызове оператора delete для указателя на объект.

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

Также как и для конструктора, не может быть определен указатель на деструктор.

Массив структур удобное средство представления и обработки табличной информации (таблиц). В качестве примера рассмотрим вариант задачи из лабораторной работы № 9, но теперь решим ее с использованием класса динамического массива структур. Дополнительно в программе реализуем операции добавления и удаления записей в массиве задолжников. Программа должна

содержать меню, позволяющее осуществить проверку всех методов класса.

Пример 1 По результатам сессии в деканате имеется список задолжников, т.е. студентов, имеющих неудовлетворительные оценки по экзаменам, зачетам, курсовым проектам и работам. Список представляет собой таблицу:

Фамилия и инициалы

Курс

Группа

Иванов А. А.

1

ИСТ-101

Сидоров Б.Б.

1

САПР-120

Каждая строка содержит информацию об одном студенте. Таблица содержит п строк. Требуется написать программу, которая печатает перечень групп, имеющих задолжников с указанием их количества в группе.

  • include <iostream.h>

  • include <fstream.h>

  • include <string.h>

  • include <iomanip.h>

  • include <stdlib.h>

  • include <conio.h> struct student

{ char name[30]; int kurs; char gr[7];

};

struct group {

char gr[7]; int ng;

};

class dmassiv // класс динамический массив структур

{

private:

student *pst; // указатель на исходную таблицу задолжников int п; // п - число строк в исходной таблице group *pz; // указатель на перечень групп, имеющих задолжников int к; //к - число групп в перечне

public:

dmassiv() { n=0; pst=NULL; k=0; pz=NULL;} // конструктор ~dmassiv(); // деструктор

void inputstudentfile (); // ввод массива задолжников из файла void outputstudent 0; // вывод массива задолжников на экран void outputgroup (); // вывод перечня групп задолжников на экран void outputgroupfile 0; // вывод перечня групп задолжников в файл void perechengroup 0; // формирование перечня групп задолжников void add (); // добавление записи в массив задолжников

void deletename (); // удаление записи из массива задолжников

};

// Ввод исходного массива задолжников из файла void dmassiv::inputstudentfile ()

{

ifstream fin; char file[10];

char iniz[7]; // рабочая переменная для инициалов

student t; // рабочая переменная для подсчета записей в файле

int i;

// очистка рабочих областей (массива задолжников и перечня) if(pst!=NULL) { delete[] pst; n=0; pst=NULL;} if(pz!=NULL) { delete[] pz; k=0; pz=NULL;} cout«’’Имя файла:”; cin » file; fin.open(file);

if( fm==NULL) {соиК<”Файл не открыт.\п”; exit(l);}

// подсчет записей в файле п=0;

do {fin »t.name » iniz »t.kurs »t.gr; n++;

}while (fin.goodO);

n—;

fin.closeO;

// выделение памяти для динамического массива pst= new student [n];

if( pst=NULL ) { cout«”HeT динамической памяти.”; getch(); exit(l);

}

// ввод массива задолжников из файла fm.open(file);

if( fm—NULL) {соШ«”Файл не открыт.\п”; exit(l);} for (i=0; i<n; i++)

{

fin » pst[i].name » iniz » pst[i].kurs » pst[i].gr ; strcat( pst[i].name, “ “); // добавление инициалов через strcat( pst[i].name, iniz); // пробел к фамилии

}

fin.close();

}

// Вывод массива задолжников на экран void dmassiv:: outputstudent ()

{

cout«’’Исходный массив структур. \п” ; cout« “Фамилия и инициалы Курс Группа \п”; for (i=0; i<n; i++)

{cout«setw( 16)«pst[i] .name; cout«setw(7)«pst[i].kurs«setw(8)«pst[i].gr;}

}

// Формирование перечня групп, имеющих задолжников void dmassiv: rperechengroup О { int ij,fl;

// вьщеление памяти для динамического массива (перечня) pz= new group [n];

if( pz=NULL ) { cout«”HeT динамической памяти.”; getchO; exit(l);

}

// очистка рабочей области (перечня) if(pz!=NULL) { delete[] pz; k=0; pz=NULL;}

// формирование перечня групп for (i=0; i<n; i++)

{ fl=i; for (j=0; j<k; j++)

if (strcmp( pst[i].gr, pz[j].gr) = 0) { fl=l; pz[j].ng++;} if (fl=l) { strcpy( pz[k].gr, pst[i].gr); pz[k].ng =1; k++;}

// Вывод перечня групп, имеющих задолжников, на экран void massiv::outputgroup ()

{ cout« ” Перечень групп, имеющих задолжников. \п” ; cout« “ Группа Кол-во \п”; for (i=0; i<k; i++)

cout« setw(8)« pz[i].gr « setw(8)« pz[i].ng « « endl;

}

// Вывод перечня групп, имеющих задолжников, в файл void dmassiv: : outputgroupfile ()

{ ofstream fout; char file[10]; int i;

cout« ”Имя файла:” ; cin » file; fout.open(file);

if( !fout.good())

{соиК<”Файл не открыт.\п”; exit(l); } for (i=0; i<k; i++)

fout« setw(8)« pz[i].gr « setw(8)« pz[i].ng « « endl; fout.close();

}

// Добавление записи в массив задолжников void dmassiv::add О { inti;

student t, // рабочая переменная для информации о добавляемом *р; // указатель для сохранения адреса исходного массива

char iniz[7]; // рабочая переменная для инициалов // ввод информации о добавляемом: cout« “Введите фамилию: cin »t.name » iniz;

strcat( t.name, “ “); // добавление инициалов через

strcat( t.name, iniz); // пробел к фамилии

cout« “Курс:

cin »t.kurs;

cout« “Группа: ”;

cin »t.gr;

p=pst; // сохранение адреса исходного массива

// выделение памяти для массива и добавление введенной записи в него

pst= new student [n+1]; if( pst=NULL)

{cout«”HeT динамической памяти.”;

getchO;

exit(l);

}

for (i-0; i<n; i++) pst[i]=p[i];

pst[n]=t; // добавление записи в массив

n++;

delete[] p; // удаление предыдущего массива

}

// Удаление записи по фамилии и группе из массива задолжников void dmassiv::deletename ()

{

int ij;

student t; // рабочая переменная для информации об удаляемом char iniz[7]; // рабочая переменная для инициалов // ввод фамилии и группы удаляемого cout« “Введите фамилию: ”; cin»t.name>> iniz;

strcat( t.name, “ “); // добавление инициалов через strcat( t.name, iniz); // пробел к фамилии cout« “Группа: ”; cin »t.gr;

// поиск и удаление записи for (i=0; i<n; i++)

if( strcmp(t.name, pst[i].name)==0 && strcmp(t.gr, pst[i].gr)=0) break;

if(i=n) {cout«t.name<” не найден. \n“; getch(); exit(l);} else { for ( j=i+1; j<n; j++) pst[j-l]=pst[j]; n—;

| . - ;yv^*-br

// Определение деструктора dmassiv: :~dmassiv()

{// очистка рабочих областей (массива задолжников и перечня) if(pst!=NULL) { delete[] pst; n=0; pst=NULL;} if(pz!=NULL) { delete[] pz; k=0; pz=NULL;}

}

/♦основная функция программы */ void main()

{

dmassiv a; // Объект класса dmassiv

int j; while (1)

{ clrscr();

cout« “1. Ввод таблицы из файла. \n”; cout« “2. Вывод таблицы на экран. \п”; cout« “3. Добавление записи в таблицу. \п”; cout« “4. Удаление записи из таблицы. \п”; cout« “5. Формирование перечня групп. \п”; cout« “6. Вывод перечня групп на экран. \п”; cout« “7. Вывод перечня групп в файл. \п”; cout« “8. Выход из программы. \п”; cout« “\п Ваш выбор (1-8) cin »j; switch(j)

{

case 1: a.inputstudentfile(); break;

case 2: a.outputstudent(); getchO; break;

case 3: a.add(); break;

case 4: a.deletename(); break;

case 5: a.perechengroup(); break;

case 6: a.outputgroupO; getchO; break;

case 7: a.outputgroupfileO; break;

case 8: cout« “Завершение рабоы.”; getch(); return;

default: cout« “ Ошибка в выборе пункта меню.; getch();

}

}

  1. ПОРЯДОК ВЫПОЛНЕНИЯ ЛАБОРАТОРНОЙ РАБОТЫ

Порядок выполнения работы описан в лабораторных работах №9, №10.

  1. ТРЕБОВАНИЯ К ОФОРМЛЕНИЮ ОТЧЕТА

  1. Оформить титульный лист с указанием темы работы.

  2. Сформулировать цель работы, зависящую от заданной преподавателем задачи; указать задание на работу.

  3. Отобразить блок-схему алгоритма.

  4. Записать текст программы.

  5. Привести результаты тестирования программы

  6. Сформулировать вывод по проделанной работе.

  1. ВАРИАНТЫ ЗАДАНИЙ

Вариангы заданий соответствуют заданиям лабораторной работы № 9. Для решения необходимо использовать классы динамического массива структур, предусмотрев выполнение дополнительно операций добавления и удаления записей в исходном массиве. Для демонстрации методов класса требуется реализовать программу меню.

  1. КРИТЕРИИ РЕЗУЛЬТАТИВНОСТИ ВЫПОЛНЕНИЯ РАБОТЫ

Критерии результативности выполнения работы совпадают с критериями, приведенными в лабораторной работе № 10.

  1. КОНТРОЛЬНЫЕ ВОПРОСЫ

  1. Что такое конструктор и для чего он предназначен?

  2. Что такое конструктор по умолчанию и как он формируется?

  3. Какое имя у конструктора и в чем особенность объявления конструктора?

  4. Что такое деструктор и его роль?

  5. Что такое деструктор по умолчанию и как он формируется?

  6. В каких случаях необходимо явно объявлять деструктор?