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

Лабораторная работа № 9 динамические массивы структур

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

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

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

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

  • осуществление процедуры поиска необходимых данных в динамическом массиве;

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

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

Принятое распределение памяти в языке C/C++ следующее:

С

Верхние адреса

Нижние адреса

тек

Свободная память

Раздел глобальных переменных и констант Код программы

Для глобальных переменных отводится фиксированное место в памяти на все время работы программы. Локальные переменные хранятся в стеке. Между ними находится область свободной памяти для динамического распределения. Наиболее важными операциями для динамического распределения памяти являются new, new [], delete, delete []. Они используются для динамического распределения свободной памяти. Операции new и new [] выделяют память, а операции delete и delete [] освобождает ее.

Две операции new предназначены для выделения участков свободной памяти и размещения в них переменных, а в случае new []

  • массивов. Продолжительность существования созданных таким образом (динамических) переменных - от точки создания до конца программы или до явного освобождения соответствующего участка памяти применением операции delete (delete [J - для удаления массивов).

Первая из рассмотренных операций предназначена для размещения в динамической памяти переменной заданного аргументом типа (кроме типов массивов) и имеет следующий вид:

new имя_типа или new имя_типа (выражение)

Вторая форма вызова помимо выделения памяти осуществляет ее инициализацию значением выражения. В обоих случаях результат операции имеет тип указателя того же типа, что и аргумент, т.е. имятипа*, и значение адреса размещенной динамической переменной. Это значение нужно сохранить в какой-либо переменной-указателе, что обеспечит в дальнейшем доступ к динамической переменной по адресу.

Операции new возвращают адрес выделенного участка памяти или, если запрашиваемой памяти нет, NULL.

Приведем пример создания и использования двух динамических переменных: int *i, *j; i= new int; j= new int (5);

*i=(*j)*(*j); // *i=25

Динамическое распределение памяти удобно использовать тогда, когда заранее неизвестно количество используемых переменных. В частности, этот механизм используется для создания динамических массивов, т.е. массивов с изменяемым количеством элементов. Для размещения динамических массивов предусмотрена специальная операция new [], вызываемая следующим образом:

new типэлемента [1

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

double *р; cin » п;

р= new double [n];

Доступ к элементам динамического массива осуществляется точно также, как к статическим, например, к 5-му элементу приведенного выше массива можно обратиться как р[4] или *(р+4).

После того как отпала необходимость в динамической переменной , ее можно удалить, освободив используемую ею память для других целей. Например, созданные ранее переменные уничтожаются следующим образом: delete i; delete j; delete [] p;

Аргументами обеих операций delete служат указатели, значения которых были получены операциями new при размещении соответствующих динамических переменных.

Желательным является использование операций delete, соответствующих каждой вызванной программой new.

Приведем несколько примеров использования динамических массивов.

Пример 1

Вычисление суммы S = £ а; • Ь,, i=l,2,...,n, где п - задается в процессе выполнения программы.

  • include <iostream.h>

  • include <stdlib.h> void main ()

{ int n,i;

double *pa, *pb, s;

cout« “ Размер массивов : ”);

cin» n;

pa = new double [n];

if (pa==NULL) {соиК<“Недостаточно памяти. \n”);return;} printf (“ Ввод массива A \ n”); for (i=0; i<n; i++ ) cin » pa[i]; pb = new double [n];

if (pb =NULL){cout«“ Недостаточно памяти. \n”; return;} cout« “ Ввод массива В \n”; for (i=0; i<n; i++) cin » pb[i];

s=0;

for (i=0; i<n; i++) s+= pa[i] * pb[i]; cout« “ s = ” « s; delete [] pa; delete [] pb;

}

Массив структур удобное средство представления и обработки табличной информации (таблиц).

Пример 2

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

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

Курс

Группа

1

Иванов А. А.

1

ИСТ-101

2

Сидоров Б.Б.

1

САПР-120

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

  • include <iostream.h>

  • include <fstream.h>

  • include <string.h>

  • include <iomanip.h>

  • include <stdlib.h> const int N=200; struct student

{ char name[30]; intkurs; char gr[7];

};

struct group

{ char gr[7]; intng;

};

// Прототипы функций

student *inputstudentfile ( int &nn);

void outputstudent ( student st[], int nn);

group *perechengroup ( student st[], int nn, int &kk);

void outputgroup (group z[], int kk);

void outputgroupfile (group z[], int kk);

// Ввод исходного массива задолжников из файла student *inputstudentfile (int &nn)

{

ifstream fin; char file[10];

char iniz[7]; // рабочая переменная для инициалов student t; // рабочая переменная подсчета записей в файле student *ps; int i;

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

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

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

fin »t.name » iniz »t.kurs »t.gr ; nn++;

}while (fm.goodO); nn—;

fin.closeO;

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

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

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

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

{

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

}

fin.close(); return ps;

}

// Вывод массива задолжников на экран void outputstudent ( student st[], int nn)

{

cout« “Фамилия и инициалы Курс Группа \п”; for (i=0; i<nn; i++)

cout«setw( 16)«st[i] .narae«setw(7)«st[i] .kurs«setw(8); cout«st[i].gr«endl;

}

// Формирование перечня групп, имеющих задолжников group *perechengroup ( student st[], int nn, int &kk)

{

int ij,fl; group *p;

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

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

for (i=0; i<nn; i++)

{

fl=i;

for ( j=0; j<kk; j++) if (strcmp(st[i].gr, pU].gr) = 0) { fl=l; p[j].ng++;} if (fl==l) { strcpy(p[k].gr, st[i].gr); p[k].ng =1; kk++;}

}

return p;

// Вывод перечня групп, имеющих задолжников, на экран void outputgroup (group z[], int kk)

{

cout«“ Группа Кол-во \n”; for (i=0; i< kk; i++)

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

}

// Вывод перечня групп, имеющих задолжников, в файл void outputgroupfile (group z[], int kk)

{

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

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

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

fout« setw(8)« z[i].gr « setw(8)« z[i].ng « « endl; fout.closeO;

}

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

{

student *pst; // указатель на исходную таблицу задолжников

int n; // n - число строк в исходной таблице

group *pz; // указатель на перечень групп, имеющих задолжников

int к; // к - число групп в перечне

pst=inputstudentfile (п);

cout« ” Исходный массив структур. \п” ;

outputstudent (pst, n);

pz=perechengroup (pst, n, k);

cout« ” Перечень групп, имеющих задолжников. \n” ;

outputgroup (pz, k);

outputgroupfile (pz, k);

delete 0 pst;

delete [] pz;

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

  1. Получение задания на лабораторную работу.

  2. Разработка алгоритма решения задачи.

  3. Составление программы на языке C++

  4. Отладка составленной программы

  5. Тестирование отлаженной программы

  6. Составление отчета о проделанной работе

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

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

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

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

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

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

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

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

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

    1. перечень фамилий с указанием числа студентов с такой фамилией;

    2. перечень имён с указанием числа студентов с таким именем;

    3. перечень отчеств с указанием числа студентов с таким отчеством;

    4. перечень групп с указанием числа студентов, обучающихся в них;

    5. перечень баллов с указанием числа студентов, набравших это количество баллов;

    6. перечень имен, встречающихся максимальное количество

раз;

    1. перечень групп, в которых максимальное количество обучающихся студентов;

' Исходные данные вводятся из файла. Результаты выводятся на экран и в файлы

    1. перечень студентов, набравших максимальное количество баллов;

    2. перечень групп, в которых максимальное количество студентов, набравших максимальное количество баллов;

    3. перечень групп, в которых средний балл студентов по группе максимален.

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

    1. перечень авторов с указанием числа их книг;

    2. перечень наименований с указанием числа книг с таким названием;

    3. перечень издательств с указанием числа книг, выпущенных

ими;

    1. перечень годов изданий с указанием числа книг, выпущенных в эти годы;

    2. перечень авторов, имеющих максимальное число книг;

    3. перечень издательств, выпустивших максимальное число

книг;

    1. перечень наименований книг, встречающихся максимальное число раз;

    2. перечень годов изданий, в которые выпущено максимальное число книг;

    3. перечень издательств, выпустивших книги авторов, которые имеют максимальное число книг в таблице данных;

    4. перечет авторов, выпустивших книги в годы издания, в которые опубликовано максимальное число книг в таблице данных.

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

    1. перечень владельцев с указанием числа их авто;

    2. перечень марок авто с указанием их числа;

    3. перечень стран производителей с указанием количества авто, выпущенных ими;

    4. перечень годов выпуска с указанием количества авто, выпущенных в эти годы;

    5. перечень владельцев, имеющих максимальное число авто;

    6. перечень стран, выпустивших максимальное количество

авто;

    1. перечень марок авто, встречающихся максимальное число

раз;

    1. перечень годов выпуска, в которые выпущено максимальное количество авто;

    2. перечень стран, выпустивших марки авто, которых имеется в таблице данных в максимальном количестве;

    3. перечень марок, выпущенных в годы, в которые произведено максимальное количество авто в таблице данных.

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

Лабораторная работа считается успешно выполненной, если:

  • отчет на бумажном носителе содержит все необходимые пункты, согласно требованиям;

  • успешно демонстрируется работа программы как на выбранных студентом исходных данных, так и на заданных преподавателем исходных данных

  • студент правильно отвечает на контрольные вопросы.

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

  1. Каково назначение операции new?

  2. Что такое динамический массив?

  3. В чем отличие операций new и new[]

  4. Каково назначение операций delete и delete[]?

  5. Как проверить, создан динамический массив или нет?

  6. Каково назначение операции индексирования?