Структура от данни запис
1. Определение
Записът е съставна статична структура от данни, която се определя като крайна редица от фиксиран брой елементи, които могат да са от различни типове. Достъпът до всеки елемент от редицата е пряк и се осъществява чрез име, наречено поле на записа.
2. Дефиниране и използване на структури
Една структура се определя чрез имената и типовете на съставящите я полета.
Дефиниция на структура:
struct име_на_структура
{
тип1 име_на_поле1;
тип2 име_на_поле2;
…
типn име_на_полеn;
};
където
име_на_структура е идентификатор;
типi е име_на_тип или дефиниция_на_тип,
а име_на_полеi е идентификатор i=1,2,…,n.
Структурите, дефинирани по този начин,могат да се използват като типове данни. Имената на полетата в рамките на една дефиниция на структура трябва да са различни идентификатори. Когато има няколко полета от един и същи тип, имената им се отделят със запетая.
Примери:
1. struct point
{double x, y;};
задава структура с име point с две полета с имена x и y от тип double. Чрез нея се задават координатите на точка в равнината.
2. struct book
{string name, author;
int year;
double price;
};
задава структура с име book с четири полета: първо поле с име name от тип символен низ, определящо името на книгата; второ поле с име author от тип символен низ, определящо името на автора на книгата; трето поле с име year от тип int, определящо годината на издаване и четвърто поле с име price от тип double и определящо цената на книгата. Чрез тази структура се задава информация за книга.
3. struct student
{int facnum;
string name;
double marks[30];
};
задава структура с име studentи с три полета: първо поле с име facnum от тип int, означаващо факултетния номер на студента; второ поле с име name от тип символен низ, определящо името на студента и трето поле с име marks от тип реален масив с 30 компоненти и означаващо оценките от положените изпити.
Възможно е за име на структура, на нейно поле и на произволна променлива на програмата да се използва един и същ идентификатор. Но тъй като това намалява читаемостта на програмата, засега не препоръчваме използването му.
Допуска се влагане на структури, т.е. поле на структура може да е от тип структура.
Пример: Допустими са дефинициите:
struct xx
{int a, b, c;
};
struct pom
{int a;
double b;
char c;
xx d;
};
Не е възможнообаче поле на структура да е от тип, съвпадащ с името на структурата.
Пример: Не е допустима дефиниция от вида
struct xxx{
xxx member; // опит за рекурсивна дефиниция
};
тъй като компилаторът не може да определи размера на xxx.
Дефиницията на структура не предизвиква отделянето на памет за съхраняване на компонентите й. Може да се постави извън функция, в началото на функция или в началото на блок. Местоположението на дефиницията определя областта на името на структурата – съответно за всички функции след дефиницията, в рамките на функцията и в рамките на блока. Най-често дефиницията се задава пред първата функция на програмата и така става достъпна за всички функции.
Тъй като дефинирането на структура чрез задаване на името на структурата определя нов тип данни, ще определим множеството от стойности и операциите и вградените функции, свързани с него.
3. Множество от стойности
Множеството от стойностите на една структура се състои от всички крайни редици от по толкова елемента, колкото са полетата й, като всеки елемент е от тип, съвместим с типа на съответното поле.
Променлива величина, множеството от допустимите стойности, на която съвпада с множеството от стойности на дадена структура, е променлива от дадения тип структура.
4. Дефиниция на променлива от тип структура
име_на_структура променлива;
Примери:
point z1, z2 = {5.6, -8.3}, z3; //Декларация с инициализация
book b1, b2, b3;
struct student s1 = {44505, “Ivan Ivanov”, {5.5, 6, 5, 6}}; //Декларация с инициализация
Деклариране на променливи може да се направи и след описание на структурата. в този случай знака ; се поставя след описанието на променливите.
Пример:
struct dvoika
{int x;
double y;
} p, q = {-2, -1.6};
5. Достъпът до полетата на структура
Достъпът до полетата на структура е пряк. Един начин за неговото осъществяване е чрез променлива от тип структурата, като променливата и името на полето на структурата се разделят с оператора точка (Фиг. 11.3). Получените конструкции са променливи от типа на полето и се наричат полета на променливата от тип структура или член-данни на структурата, свързани с променливата.
Операторът . е лявоасоциативен и има приоритет равен на този на () и [].
променлива_структура.име_на_поле
Примери:
С променливите z1, z2, z3 се свързват променливите от тип double:
z1.x, z1.y, z2.x, z2.y, z3.x и z3.y
а с b1, s1 и y –
b1.name - от тип string, b1.author – от тип string, b1.year - от тип int, b1.price - от тип double,
s1.facnum – от тип int, s1.name - от тип string, s1.marks - от тип string,
y.a - от тип int, y.b - от тип double, y.c - от тип char,
y.d - от тип xx ис полета y.d.a, y.d.b и y.d.c от тип int.
Допълнение: Две структури, дефинирани по един и същ начин, са различни. Например, дефинициите
struct str1{
int a;
int b;
};
и
struct str2{
int a;
int b;
};
определят два различни типа. Дефинициите
str1 x;
str2 y = x;
предизвикват грешка заради смесване на типовете (x и y са от различни типове).
6. Операции и вградени функции
а) над полетата на променливи от тип структура
Всяко поле на променлива от тип структура е от някакъв тип. Всички операции и вградени функции, допустими за данните от този тип, са допустими и за съответното поле.
б) над променливи от тип структура
- Възможно е на променлива от тип структура да се присвои стойността на вече инициализирана променлива от същия тип структура или стойността на израз от същия тип.
Пример: Допустими са присвояванията
z3 = z2;
p = q;
- Възможно е формален параметър на функция, а също резултатът от изпълнението й, да са структури. Структури с големи размери обикновено се предават чрез указатели или псевдоними на структури. Така се спестяват ресурси. Освен това, тези начини за предаване са по-сигурни.
Задача: Да се напише програма, която:
а) въвежда факултетните номера, имената и оценките по 1 предмет на студентите от една група;
б) сортира в низходящ ред по успех данните;
в) извежда в табличен вид въведените данни;
Данните за студент се дефинират чрез структурата:
Първи начин за решение
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
struct student
{
int facnom;
string name;
double marks;
};
void read_student(student& s)
{
cout << "fak. nomer: ";
cin >> s.facnom;
cin.ignore(); /* Use 'ignore' to remove the '\n' from the last input */
cout << "name: ";
getline(cin, s.name);
cout << "mark: ";
cin >> s.marks;
}
void print_student(const student& stud)
{
cout << setw(6) << stud.facnom
<< setw(30) << stud.name
<< setw(6) << stud.marks;
}
void sortStudents(int n, student a[])
{
for (int i = 0; i <= n-2; i++)
for (int j = i+1; j <= n-1; j++)
if (a[i].marks < a[j].marks)
swap(a[i], a[j]);
}
int main()
{
student arrStudents[30];/* Array of structures "student" */
int n;
do
{
cout << "number of students? ";
cin >> n;
}
while (n < 1 || n > 30);
int i;
for (i = 0; i <= n-1; i++) /* Fill the array of structures */
read_student(arrStudents[i]);
sortStudents(n, arrStudents);
cout << "Students: \n";
for (i = 0; i <= n-1; i++)
{
print_student(arrStudents[i]);
cout << endl;
}
return 0;
}
Втори начин за решение
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
struct student
{
int facnom;
string name;
double marks;
};
void read_student(student a[],int n)/* Fill the array of structures */
{
for (int i = 0; i <= n-1; i++)
{
cout << "fak. nomer: ";
cin >> a[i].facnom;
cin.ignore(); /* Use 'ignore' to remove the '\n' from the last input */
cout << "name: ";
getline(cin, a[i].name);
cout << "mark: ";
cin >> a[i].marks;
}
}
void print_student(student a[],int n)
{
for (int i = 0; i <n; i++)
cout << setw(6) << a[i].facnom
<< setw(30) << a[i].name
<< setw(6) << a[i].marks<<endl;
}
void sortStudents(student a[],int n)
{
for (int i = 0; i <n-1; i++)
for (int j = i+1; j <n; j++)
if (a[i].marks < a[j].marks)
swap(a[i], a[j]);
}
int main()
{
student arrStudents[30];/* Array of structures "student" */
int n;
do
{
cout << "number of students? ";
cin >> n;
}
while (n < 1 || n > 30);
read_student(arrStudents,n);
sortStudents(arrStudents,n);
cout << "\n\nStudents: \n";
print_student(arrStudents,n);
return 0;
}