Лабораторная работа 8. Динамические списки
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

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

 

Теоретические сведения

Структуры

В отличие от массива, все элементы которого однотипны, структура может содержать элементы разных типов. Если нам надо хранить в программе данные по анкетам студентов, а в анкетах присутствуют как строковые данные (фамилия, имя, отчество), так и числовые (год рождения, например), то для хранения таких данных не подойдет такой тип данных как массив. В Паскале для этого служит тип данных запись, в С и С++ - тип данных структура. В С++ структура является видом класса и обладает всеми свойствами класса, но во многих случаях достаточно использовать структуры так, как они определены в языке С.

Структура – это одна или несколько переменных одного или разных типов, которые для удобства работы сгруппированы в одну языковую конструкцию под одним именем.

Для объявления структуры в программе используется ключевое слово struct, за которым обычно следует имя структуры. Затем в фигурных скобках вы указываете тип и имя одного или нескольких элементов. После правой фигурной скобки вы можете (это не обязательно) объявить переменные данной структуры:

struct name                         // name – имя структуры

{ int name1;              // объявление элементов структуры

float name2;

} variable;                 // объявление переменной

Например, следующее определение создает структуру, содержащую информацию о служащем:

struct employee

{ char name[64];

  long empl_id;

  float salary;

  char phone[10];

  int office_n;

};

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

employee boss, worker, new_empl;

В данном случае объявляются три переменные структуры employee. Можно их же объявить так:

struct employee boss, worker, new_empl;

Ключевое слово struct является обязательным при программировании на С, так что некоторые программисты могут включать его по привычке. Однако в С++ использовать ключевое слово struct в случае объявления переменных-структур не является обязательным.

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

Доступ к элементам структуры осуществляется с помощью точки записью вида

имя_структурной_переменной.имя_поля

Например,

worker.empl_id = 12345;

worker.salary = 25000.00;

worker.office_n = 10;

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

Пример

#include <iostream>

#include <string.h>

main( )

{ struct employeer

{ char name[64];

  long empl_id;

  float salary;

  char phone[10];

  int office_n;

} worker;

// заполняем структуру worker конкретными данными

strcpy (worker.name, “Джон Дой”);

worker.empl_id = 12345;

worker.salary = 25000.00;

strcpy (worker.phone, “555-1212”);

worker.office_n = 10;

// выведем информацию о рабочем на печать

cout << “Служащий:” << worker.name << endl;

cout << “Телефон:” << worker.phone << endl;

cout << “Номер служащего:” << worker.empl_id << endl;

cout << “Оклад:” << worker.salary << endl;

cout << “Офис:” << worker.office_n << endl;

}

Как видите, присваивание целому элементу и элементу с плавающей точкой осуществляется просто с помощью оператора присваивания. В строковую переменную данные копируются с помощью стандартной строковой функции.

Данные можно ввести с клавиатуры.

struct addr

{ char town[10];

char street[10];

int block;

int flat;

};

addr home;

// ввод данных с клавиатуры

cout << “Город:”;

cin >> home.town;

cout << “Улица:”;

cin >> home.street;

cout << “Дом:”;

cin >> home.block;

cout << “Квартира:”;

cin >> home.flat;

// вывод адреса, введенного с клавиатуры

cout << “The address is” << home.town << home.street << home.block << home.flat << endl;

Можно проинициализировать переменную структурного типа сразу в объявлении:

addr home = {“Москва”, “Стромынка”, 20, 102};

cout << “The address is” << home.town << home.street << home.block << home.flat << endl;

Очевидно, что порядок следования инициализаторов (присваиваемых значений) соответствует порядку объявленных в структуре элементов.

 

Псевдонимы структур

При объявлении структуры иногда используется ключевое слово typedef, которое создает псевдонимы типов данных. Надо помнить, что typedef не определяет нового типа данных, а только связывает объявление типа данных с именем, называемым псевдонимом:

typedef объявление Псевдоним;

Можно создать псевдоним для переменной любого типа, как базового (стандартного), так и производного. Обычно псевдоним начинается с заглавной буквы.

Например,

typedef int Counter; // Counter становится псевдонимом int

Теперь можно использовать Counter вместо типа int во всех объявлениях целых переменных.

Создадим псевдоним для структурного типа:

typedef struct prim

{ char name;

int sum; } Newstr;

Newstr st, as[8];

prim pr_st, pr_as[8];

В этом примере введен структурный тип prim, и ему дополнительно с помощью  typedef присвоено имя Newstr. В дальнейшем это новое имя использовано для определения структуры st и массива структур as[8]. С помощью структурного типа prim определены такие же объекты: структура pr_st и массив структур pr_as[8]. Таким образом, основное имя структурного типа (prim) и имя, дополнительно введенное с помощью typedef (Newstr), совершенно равноправны.

При создании псевдонима структурной переменной допустимо отсутствие идентификатора структуры.

Пример .

typedef struct date

{ int day;

int month;

} Date;

или

 typedef struct  

{ int day;

int month;

} Date;

В любом случае псевдоним Date также представляет объявленный структурный тип данных.

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

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

struct mistake

{ mistake s;

int m;

};                        // ошибка: такой структуры быть не может

Элементом определяемой структуры может быть структура, тип которой уже определен – получаем вложенную структуру.

 

Вложенные структуры

Объявим структуру для запоминания времени:

typedef struct 

{ int hour;

  int minute,

  int second;

} Time;

Объявим структуру для запоминания даты:

 typedef struct 

{ int day;

  int month,

  int year;

} Date;

Теперь можно построить вложенную структуру DateTime:

 typedef struct 

{ Date today;

  Time now,

} DateTime;

Для доступа к вложенным полям структур используется число точек, достаточное для осуществления такого доступа. Например,

DateTime dt; // описали переменную

dt.today.year = 2011;

dt.now.minute = 13;

При этом слева от точки располагается имя структурной переменной, а справа – имя поля структуры: dt – структурная переменная, today – поле структурной переменной dt; today – структурная переменная, year – ее поле; now – структурная переменная, minute – ее поле.

Инициализация вложенных структур осуществляется с помощью конструкций вида:

DateTime birthtime = { {27, 01, 1991}, {06, 05, 00} };

 

Массивы структур

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

Существуют две основные комбинации:

- массивы структур;

- структуры с полями, являющимися массивами.

Описание массива структур совершенно аналогично описанию массива любого другого типа. Каждый элемент массива представляет собой структуру объявленного типа.

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

addr Homes[10];

Индекс массива присоединяется к имени массива структурного типа:

Homes[3].street; // правильно

Homes.street[3]; // так неправильно!

В то же время Homes[2].street[4] – вполне допустимая конструкция с точки зрения компилятора, если street является массивом. При этом мы получаем доступ к 5-ому элементу массива street, который в свою очередь является членом 3-го элемента массива Homes. Таким образом мы рассмотрели использование массива в качестве элемента структуры.

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

Пример

Дан массив структур, содержащий сведения об успеваемости по программированию группы из 18 студентов. Структура содержит следующие сведения: фамилию и инициалы студента, 6 оценок по лабораторным работам, отражающих его текущую успеваемость в течение семестра. Вывести на экран список неуспевающих студентов (имеющих хотя бы одну двойку).

#include <iostream>

const int GROUP = 18;

main ( )

{ int i, flag;

struct gruppa

  { char fam[18];

     int progr[5];

   } Gruppa[GROUP];

cout << “Введите данные” << endl;

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

  { cout << “фамилия:”

     cin >> Gruppa[i].fam;

     for (int j = 0; j <= 5; j++)

       { cout << j+1 << “- я оценка”;

          cin >> Gruppa[i].progr[j];

        }

    }

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

for (I = 0; I < GROUP; i++)

   { flag = 0;

      for (int j = 0; j <= 5; j++)

         if (Gruppa[i].progr[j] == 2) flag = 1;

      if (flag == 1) cout << Gruppa[i].fam << endl;

    }

return 0;

}

Дата: 2019-05-28, просмотров: 194.