Структура —
це сукупність різнотипних елементів, яким присвоюється одне ім’я (воно може
бути відсутнім), що займає одну ділянку пам’яті. Елементи, що складають
структуру, називаються полями.
Змінна типу структура, як і будь−яка змінна,
повинна бути описана. Цей опис складається з двох кроків: опису шаблону (тобто
складу) або типу структури та опису змінних структурного типу.
Синтаксис опису
структури має вигляд:
struct [<ім’я структури>]
{
<тип 1> ім’я поля 1;
<тип 2> ім’я поля 2 . . .;
}
р1, р2 . . .;
де struct — службове слово;
<ім’я структури> —
ім’я типу структура (може бути відсутнім);
<тип 1>, <тип 2> —
імена стандартних або визначених типів;
ім’я поля 1, ім’я поля 2,… —
імена полів структури;
р1, р2 . . .; —
імена змінних типу структура.
Наприклад, для знаходження середнього бала, отриманого
студентами в період сесії з дисциплін «Математика», «Фізика» та
«Програмування», визначимо таку структуру:
struct stud
{ char fam [25];
// ПІП
int mat, fiz, prg;
// предмети
float sb; // середниій балл
} st1, st2;
Змінні st1 і st2 можна оголосити окремим
оператором, наприклад:
struc stud stl st2;.
Ініціювання полів структури слід здійснювати або при її
описі, або в тілі програми. При описі структури ініціювання полів виглядає,
наприклад, так:
struct
stud
{
char fam [25];
int mat,fiz, prg;
float sb;
}
st1 = {"Кравченко Н. С.", 4, 5, 5};
st2 = {"Тесленко А. М.", 3, 4, 5};
Якщо ініціювання виконується в тілі програми, то для звернення
до імені поля треба спочатку записати ім’я структурної змінної, а потім ім’я
поля. Ці обидва записи відокремлюються крапкою і являють собою складене ім’я.
Отже, у випадку появи змінної st1 у програмі для її
ініціювання можна записати stud
st1 =
{“Кравченко Н. С.”, 4, 5, 5}; або ініціювання виконується за
допомогою складених полів. Розглянемо ілюстраційну програму:
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
main ( )
{ struct stud
//−−−−−−−−−−−−−−−−−−−−
опис структури
{ char fam
[20];
int
mat, fiz, prg;
float
sb;
} st1, st2;
strcpy
(st1.fam, "Кравченко Н. С.");
st1 .mat =
4;
st1 .fiz =
5;
st1 .prg =
5;
st1.sb =
float (st1.fiz + st1.mat + st1.prg)/3;
st2 =
st1;
puts
(st2.fam); //−−−−−−−−−−−−−−−−
вивід прізвища
cout
<< st2.mat << st2.fiz << st2.prg
<< st2.sb << endl;
getch(); //затримка екрану
}
У наведеній програмі організується присвоювання всім полям
структури st1
відповідних значень. Слід зауважити, що поле st1.fam одержує значення шляхом
застосування функції strcpy
(st1.fam, “Кравченко И. С.”);. Структурна змінна st2 того ж типу, що і st1, тому справедлива
операція st2 = st1;.
Якщо функція використовує тільки один структурний тип, то цей тип
можна оголосити без імені. Тоді раніше розглянуту структуру можна оголосити
таким чином:
struct
{
char fam [25];
int
mat, fiz, prg;
float sb;
} stl,
st2;
Коли при описі структур у деякій функції або в межах видимості
змінних у різних функціях є багато (але не всі) однакових полів, то їх слід
об’єднати в окрему структуру. Її можна застосовувати при описі інших структур,
тобто поля структури можуть самі бути типу struct. Це називається вкладеністю структур —
її можна використати, наприклад, якщо треба обробляти списки студентів та
викладачів університету. Студентські списки містять дані: прізвище та ініціали,
дата (день, місяць, рік) народження, група та середній бал успішності, а в
списках викладачів присутні такі дані: прізвище, ініціали, дата народження,
кафедра, посада. У процесі обробки списку студентів і списку викладачів можна
оголосити відповідно такі структури:
struct
stud
{ char fio [25];
int den, god;
char mes [10];
char
grup;
flout sb; }
struct vykl
{ char fio [25];
int den, god;
char mes [10];
char kaf, dolg;
}
В оголошених типах однакові поля можна об’єднати в окрему
структуру і застосовувати її при описі інших типів. Поетапно це виглядає так:
struct
spd
{
char fio [25];
int
den, god;
char
mas[10]; }
struct stud
{ spd dr;
char grup;
float sb}
st1, st2;
struct vykl
{ spd dr;
char kaf [10];
char dolg [15];
} pr1, pr2;
У структурах stud
і prep для оголошення поля, що містить дані про прізвище і дату народження, використовується раніше описаний тип spd. Тепер до поля fio, den, god, mes можна звернутися, використовуючи запис st1.dr.fio, наприклад, при зверненні до функції введення:
gets (st1.dr.fio);
або gets
(pr1.dr.fio);.
Після оголошення структурного типу змінних для роботи з
їхніми полями можна застосовувати і покажчики, тоді опис структури матиме
вигляд:
struct stud
{ char fam [25];
int mat, fiz,
prg;
float sb;
} st1, *pst;
Доступ до полів може здійснюватися двома способами:
з використанням операції розіменування «*», тобто
gets ((*pst).fam); (*pst).fiz = 5;
з використанням покажчика *−>*, наприклад,
gets (pst −> fam);
pst−> fiz = 5; тощо.
Крім того, до полів змінної st1 можна звертатися,
вказуючи поля через операцію «.», як це робилося раніше.
Дані типу структура можна об’єднати в масиви, тоді для
розглянутого вище ілюстраційного прикладу з урахуванням кількості студентів,
структуру можна записати так:
struct stud
{ char fam [20];
int mat, fiz, prg;
float sb;
} spis[15], *sp = &spis[0];.
У випадку, коли масив описується десь у тексті програми, тобто не саме після опису структури, його можна оголосити у вигляді: stud
spis [15]; — масив типу структура з ім’ям stud,
що містить відповідну інформацію про групу із 15 студентів.
Доступ до елементів масиву типу структура здійснюється із
застосуванням індексу або через покажчик−константу, яким є ім’я масиву,
тобто одним з таких способів:
strcpy (spis[1].fam, ” “);
spis[1].fiz = 5;
або
strcpy ((sp + 1) −>
fam, ” “);
(sp + 1) −> fiz =
5;
або
strcpy ((*(spis + 1)).fam, ”
“);
(*(sp + 1)).fiz = 5;.
У останньому виразі (*(spis + 1)).fiz = 5; потрібна зовнішня пара
дужок, тому що операція
«.» («крапка») має пріоритет вище, ніж операція розіменування «*».
Поля структури можуть також бути масивами. Наприклад, у
розглянутій структурі stud
можна оцінки з різних предметів об’єднати в масив. Тоді структуру слід описати
у вигляді:
struct
stud1
{
char fam [25];
int pred [3];
float sb
} spis[15], *ps
= &spis[0];.
Звернення до полів здійснюватиметься одним із способів:
((*ps).fam)
(ps−>pred [0]),
наприклад,
gets ((*ps).fam);
сіn >> ps −> pred[0]
>> ps −> pred[1] >> ps −> pred[2];
або сіn >> ps −> *(pred + 0)
>> ps −> *(pred + 1) >> ps −> *(pred +
2).
Доцільно також зазначити, що бібліотека stdlib.h містить спеціальні функції для пошуку та сортування структурних змінних.
Розглянемо використання структурного типу на прикладах.
Приклад Увести в комп’ютер
відомість успішності групи студентів, які здали сесію з дисциплін
«Математика», «Фізика» і «Програмування», та обчислити:
середній бал кожного студента;
середній бал групи за кожним предметом;
вивести на екран прізвища відмінників з програмування.
Розглянемо перший варіант реалізації поставленої задачі,
що може мати вигляд:
// Р8_1_ 1.СРР — обробка відомості успішності групи
студентів
//−−−−−−−−−−−−−−−−−−−−−−−−використання
даних типу структура
#include
<iostream.h>
#include <string.h>
#include <conio.h>
void main()
{ const n = 5; //n — кількість студентів
int і;
float sm, sf, sp;
/*
sm, sf.sp — сумма оцінок групи відповідно по матиматиці, физиці, програмуванню */
struct stud
{ char fam[25];
int mat, fiz, prg;
float sb;
} ved[n]; //ved[n] — масив студентів (відомість)
sm = sf = sp = 0;
//−−−− ввод и обробка інформації про студентів і їх успішність
for (і = 0; і < n; i++)
{ cout <<"*** Введіть інформацію про "<< (i+1) << " студента\n";
{ cout<<<<"Введіть прізвище і ініціали\n";
gets(ved[i]. fam);
cout <<"Оцінки по матим., физиці и
програм.\n";
cin >> ved[i].mat
>> ved[i].fiz >> ved[i].prg;//−−−−−−−−−−−−−−−−−−−−−
средній бал студента за сесію
ved[i].sb = (float(ved[i].mat + ved[i].fiz +
ved[i].prg))/3;//−−−−−−−−−−−−−−−−−−−−−
сумування оцінок в групі по предметах
sm += ved[i].mat;
sf += ved[i].fiz;
sp += ved[i].prg;
}
}
//−−−−−−−−−−−−−−−−−−−−−
вивід результатів
cout << ''\n******* Результати
сесії\n";
cout.precision(3);
for (і = 0; і < n; i++)
cout<<i+1<< "
"<< ved[i].fam << " матем. = " << ved[i].mat << " физика = "<< ved[i].fiz << "програм. = " <<ved[i].prg << " ср. балл = "
<< ved[i].sb << "\n";
cout << "\n\nСередній балл групи по матиматиці = "<< sm/n;
cout << "\nСередній балл групи
по физиці = "<< sf/n;
cout << "\nСередній балл групи по
програмуванню = "<<sp/n;
cout << "\n\n***** Відмінники
по програмуванню: \n";
for (і = 0; і < n; i++)
if (ved[i].prg ==
5) cout << ved[i].fam <<"\n";
getch ();
}