Лекция № 6

Тема: «Работа со структурами в С++»

 

План

1. Понятие и описание структуры

2. Операции со структурой

3. Описание массива структур

4. Примеры обработки массивов структур

 

1. Понятие и описание структуры

Часто в реальных программах приходится обрабатывать данные о реальных объектах, которые описываются множеством разнотипных свойств. Например, объект «студент» описывается свойствами: фамилия, имя, отчество, год рождения, средний балл и т.п.

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

В языке С++ имеется инструмент описания таких объектов. Для этого используют понятие структуры – пользовательского типа данных, позволяющего с  помощью одной переменной описать множество свойств сложного объекта. При этом свойства объекта называют полями структуры.

Для описания структуры используют конструкцию вида:

 

struct имя_структуры

{

тип имя_поляа1;

тип имя_поля2;

. . .

тип имя_поля n;

};

 

Если несколько свойств имеют один тип, то их перечисляют через запятую после указаний соответствующего типа:

 

struct имя_структуры

{

тип имя_поля1, имя_поля2;

тип имя_поля3, имя_поля4;

. . .

};

 

Например, структура объекта «студент» может иметь вид:

 

struct student

{

char fam[15], imya[10], otch[15]; //ФИО

int god; //год рождения

float srbal; //средний балл

};

 

В программе на С++ принято описывать структуры до указания заголовка главной функции программы int main().

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

Приведем полный пример начала программы для описания структуры объекта «студент» и соответствующей переменной:

 

//подключаем заголовочные файлы

#include <iostream.h>

 

//описываем структуру

struct student

{

char fam[15], imya[10], otch[15]; //ФИО

int god; //год рождения

float srbal; //средний балл

};

 

//заголовок программы

int main()

{

//описываем переменную st для работы со структурой

student st;

. . .

return 0;

} (начало)

 

2. Операции со структурой

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

 

имя_переменноймя_поля

 

Например, присвоим полю fam значение Иванов:

 

strcpy(st.fam,”иванов”);

 

Полю god присвоим 1992:

 

st.god=1992;

 

Введем данные о студенте:

 

//выводим заголовок

cout<<"Введите данные о студенте\n";

//вводим фамилию

cout<<"-фамилия: ";

cin.getline(st.fam,15);

//вводим имя

cout<<"-имя: ";

cin.getline(st.imya,10);

//вводим отчество

cout<<"-отчество: ";

cin.getline(st.otch,15);

//вводим год рождения

cout<<"-год рождения: ";

cin>>st.god;

//вводим средний балл

cout<<"-средний балл: ";

cin>>st.srbal;

 

Выведем данные о студенте:

 

//выводим заголовок

cout<<"Данные о студенте:\n";

//выводим фамилию

cout<<"-фамилия: "<<st.fam<<"\n";

//выводим имя

cout<<"-имя: "<<st.imya<<"\n";

//выводим отчество

cout<<"-отчество: "<<st.otch<<"\n";

//выводим год рождения

cout<<"-год рождения: "<<st.god<<"\n";

//выводим средний балл

cout<<"-средний балл: "<<st.srbal<<"\n";

 

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

Например, допускается код вида:

 

//описываем переменные для работы со структурой

student st,rez;

 

//вводим данные о студенте

//выводим заголовок

cout<<"Введите данные о студенте\n";

//вводим фамилию

cout<<"-фамилия: ";

cin.getline(st.fam,15);

//вводим имя

cout<<"-имя: ";

cin.getline(st.imya,10);

//вводим отчество

cout<<"-отчество: ";

cin.getline(st.otch,15);

//вводим год рождения

cout<<"-год рождения: ";

cin>>st.god;

//вводим средний балл

cout<<"-средний балл: ";

cin>>st.srbal;

 

//присваиваем данные о студенте переменной rez

rez=st;

 

В результате в переменных st и rez находится информация об одном и том же студенте. (начало)

 

3. Описание массива структур

Если программа работает со структурами, то очень редко эта структура выступает в одном экземпляре. Чаще всего приходится иметь дело с набором однородных структур. Например: группа студентов, каталог товаров, список книг и т.п.

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

Например, описать группу из 30 студентов.

 

//подключаем заголовочные файлы

#include <iostream.h>

 

//описываем структуру

struct student

{

char fam[15], imya[10], otch[15]; //ФИО

int god; //год рождения

float srbal; //средний балл

};

 

//заголовок программы

int main()

{

//описываем группу (массив) из 30 студентов

student group[30];

. . .

}

 

В данном примере описан массив с именем group. Каждый элемент в нем (group[i]) является переменной типа student, то есть структурой.

При работе с массивами структур удобно использовать цикл for. При этом для обращения к полю отдельного элемента массива используют запись вида:

 

имя_массива[i].имя_поля

 

Как и при обработке обычного массива необходимо помнить, что нумерация элементов в массиве начинается с 0. Поэтому номер элемента в массиве всегда на 1 меньше его фактического номера в наборе данных.

 

Например, 5 студенту в поле god записать значение 1990

 

group[4].god=1990; //пятый студент под номером 4 в массиве

 

Десятому студенту в поле fam записать Фролов

 

strcpy(group[9].gam,”фролов”); //десятый студент под номером 9 в массиве (начало)

 

4. Примеры обработки массивов структур

Для демонстрации обработки массива структур решим следующую задачу.

Пусть объект «студент» описывается свойствами:

- фамилия;

- имя;

- отчество;

- пол;

- рост (см);

- средний балл.

Необходимо описать массив из 30 студентов и организовать ввод данных об n студентах (n<=30)

 

//подключаем заголовочные файлы

#include <iostream.h>

//описываем структуру «студент»

struct student

{

char fam[15], imya[10], otch[15], pol;

int rost;

float srbal;

};

int main()

{

system("chcp 1251>nul");

//описываем массив из 30 студентов

student group[30];

//описываем вспомогательные переменные

int i,n;

//вводим реальное количество студентов

cout<<"Введите количество студентов в группе: ";

cin>>n;

//очищаем память от кода клавиши enter

cin.get();

 

//организуем цикл по массиву структур

for (i=0; i<=n-1; i++)

{

//вводим данные об очередном студенте

cout<<"Введите данные о "<<i+1<<"-м студенте:\n";

//вводим фамилию

cout<<"-фамилия: ";

cin.getline(group[i].fam,15);

//вводим имя

cout<<"-имя: ";

cin.getline(group[i].imya,10);

//вводим отчество

cout<<"-отчество: ";

cin.getline(group[i].otch,15);

//вводим пол

cout<<"-пол: ";

cin>>group[i].pol;

//вводим рост

cout<<"-рост: ";

cin>>group[i].rost;

//вводим средний балл

cout<<"-средний балл: ";

cin>>group[i].srbal;

//очищаем память от кода клавиши enter

cin.get();

}

return 0;

}

 

На основании введенных данных определить средний рост мужчин и средний рост женщин.

 

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

float summ, sumw, kolm, kolw;

//организуем цикл по всему массиву

for (summ=0, sumw=0, kolm=0, kolw=0, i=0; i<=n-1; i++)

{

//если пол мужской

if (group[i].pol=='м')

{

//считаем сумм ростов мужчин

summ+=group[i].rost;

//количество мужчин увеличиваем на 1

kolm++;

}

//если пол женский

else

{

//считаем сумму ростов женщин

sumw+=group[i].rost;

//количество женщин увеличиваем на 1

kolw++;

}

}

 

//выводим результат на экран

//если количество мужчин больше 0

if (kolm>0)

//выводим средний рост мужчин

cout<<"Средний рост мужчин: "<<summ/kolm<<"\n";

//если количество мужчин равно 0

else

//выводим сообщение, что мужчин нет

cout<<"Мужчин в группе нет\n";

 

//если количество женщин больше 0

if (kolw>0)

//выводим средний рост женщин

cout<<"Средний рост женщин: "<<sumw/kolw<<"\n";

//если количество женщин равно 0

else

//выводим сообщение, что женщин нет

cout<<"Женщин в группе нет\n";

 

 

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

 

//описываем вспомогательные переменные

int kol,rost;

//вводим значение роста для поиска

cout<<"Введите нужное значение роста: ";

cin>>rost;

cin.get();

//организуем цикл по массиву структур

for (kol=0,i=0; i<=n-1; i++)

//если рост текущего студента больше заданного

if (group[i].rost>rost)

//увеличиваем количество студентов на 1

kol++;

//выводим результат на экран

cout<<"Количество студентов с ростом больше "<<rost<<" равно "<<kol<<"\n";

 

Вывести на экран ФИО самого высокого студента группы.

 

//описываем вспомогательные переменные

float max;

int nom;

//организуем цикл по массиву структур

//вначале максимальное значение равно первому элементу

//номер этого элемента запоминает в переменную nom

for (max=group[0].rost, nom=0, i=0; i<=n-1; i++)

//в цикле находим максимальное значение

//и его порядковый номер

if (group[i].rost>max)

{

max=group[i].rost;

nom=i;

}

//выводим на экран элемент массива с номером nom

cout<<"Самый высокий студент: "<<group[nom].fam

<<" "<<group[nom].imya<<" "<<group[nom].otch<<"\n";

 

Вывести на экран фамилию и имя студентов, которые получают стипендию (средний балл не менее 4).

 

//выводим заголовок

cout<<"Список студентов, получающих стипендию:\n";

//организуем цикл по массиву структур

for (i=0; i<=n-1; i++)

//если средний балл студента не менее 4

if (group[i].srbal>=4)

//выводим на экран ФИО студента

cout<<group[i].fam<<" "<<group[i].imya<<" "

<<group[i].otch<<"\n";

 

На экран вывести данные о студентах, фамилии которых начинаются на заданное буквосочетание (буквосочетание ввести с клавиатуры).

 

//описываем переменную для ввода фамилии

char fam[15];

//вводим фамилию для поиска

cout<<"Введите фамилию для поиска: ";

cin.getline(fam,15);

//организуем цикл по массиву структур

for (i=0; i<=n-1; i++)

//если фамилия студента равна введенной фамилии

if (strnicmp(group[i].fam, fam, strlen(fam))==0)

//выводим на экран данные о студенте

cout<<group[i].fam<<" "<<group[i].imya

<<" "<<group[i].otch<<"\n";

 

Вывести на экран ФИО мужчин-отличников.

 

//выводим заголовок

cout<<"Список мужчин-отличников:\n";

//организуем цикл по массиву структур

for (i=0; i<=n-1; i++)

//если у студента пол мужской

//и средний балл равен 5

if (group[i].pol=='м' && group[i].srbal==5)

//выводим данные о студенте

cout<<group[i].fam<<" "<<group[i].imya

<<" "<<group[i].otch<<"\n"; (начало)