§17 Структуры

Понятие структуры данных

Структурой данных называется составной тип в котором под одним именем объединены данные различных типов. Структура данных (наряду с классом) представляет собой абстрактный тип данных определяемый разработчиком. Структура может также включать в себя и другие абстрактные типы (например, string). После объявления абстрактного типа можно создавать переменные и массивы, указатели и ссылки, объявлять функции и передавать параметры абстрактного типа, присваивать значения одних переменных значениям других переменных одного и того же абстрактного типа.
Переменные, составляющие структуру, называются её членами (member) или полями. Помимо полей, структуры могут содержать функции-члены, иначе называемые – методами.

Определение структуры

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

struct student {
	double weight;
	double height;
	char stage;
	int age;
	string name;
};

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

struct student {
	double weight;
	double height;
	char stage;
	int age;
	string name;
} Boris, Sveta, Alex, Margo;

Правилом хорошего тона в программировании считается отделение определения структур от объявления переменных этих структур.
Чаще всего структуры определяются вне тела главной функции main(). Делается это для того, чтобы абстрактные типы стали доступными и другим функциям.

Доступ к членам

Операция “точка”

Для того, чтобы получить доступ к членам структуры необходимо использовать операцию “точка” (.)
Синтаксис:
Имя_переменной.Имя_члена

student Masha;
Masha.age = 18;
cout << Masha.age << endl;
Операция "стрелка"

Если получен указатель абстрактного типа, то доступ к элементам можно получить с помощью операции "стрелка" (->)

student Serge;
student *p = new student;
student *t = &Serge;
p -> weight = 65;
t -> height = 160;
cout << p -> weight << endl;
cout << t -> height << endl;
Примечание. Операция p -> atrib означает тоже самое, что и (*p).atrib.

Инициализация переменных абстрактного типа

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

student Serge {62, 175, 'A', 16, "Abrosimov S. I."};
student *p = new student {65, 180, 'C', 17, "Lukin A. S."};
cout << Serge.name << endl;
cout << p -> weight << endl;

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

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

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

Программа cpp-17.1.
#include <iostream>
#include <array>
#include <string>
using namespace std;

struct student {
	double weight;
	double height;
	char stage;
	int age;
	string name;
};

void mean(array<student, 30>&, string&, const int);

int main() {
	array<student, 30> card;
	for (auto &r: card) {
		student per;
		cout << "name => ";   cin >> per.name;
		cout << "stage => ";  cin >> per.stage;
		cout << "age => ";    cin >> per.age;
		cout << "weight => "; cin >> per.weight;
		cout << "height => "; cin >> per.height;
		r = per;
	}
	string str1 = "Cредний возраст";
	string str2 = "Cредний рост";
	string str3 = "Cредний вес";
	cout << "Какие средние параметры вы хотите определить?\n"
            "Введите одну из цифр:\n"
         << "1 - " << str1 << "\n"
         << "2 - " << str2 << "\n"
            "3 - " << str3 << "\n"
            "и нажмите Enter";
    int n; cin >> n;
    switch (n) {
        case 1: mean(card, str1, 1); break;
        case 2: mean(card, str2, 2); break;
        case 3: mean(card, str3, 3); break;
    }
	return 0;
}

void mean(array<student, 30> &aver, string &mstr, const int x) {
    double s = 0;
    if (x == 1) for (auto &r : aver) s += r.age;
    if (x == 2) for (auto &r : aver) s += r.height;
    if (x == 3) for (auto &r : aver) s += r.weight;
    cout << mstr << " - " <<  s / aver.size() << endl;
}

Передача структуры в функцию

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

Программа cpp-17.2
#include <iostream>
#include <array>
#include <string>
using namespace std;

struct student {
	double weight;
	double height;
	char stage;
	int age;
	string name;
};

void swap_str(student&, student&);

template <typename T>
void swap_mem(T &a, T &b) {
    T temp;
    temp = a;
    a = b;
    b = temp;
}

int main() {
    student pr1 {62, 175, 'A', 16, "Abrosimov S. I."};
   	student pr2 {65, 180, 'C', 17, "Lukin A. S."};
   	cout << pr1.name << endl;
   	cout << pr2.name << endl;
   	swap_str(pr1, pr2);
   	cout << pr1.name << endl;
   	cout << pr2.name << endl;
	return 0;
}

void swap_str(student &prs1, student &prs2) {
    swap_mem(prs1.weight, prs2.weight);
    swap_mem(prs1.height, prs2.height);
    swap_mem(prs1.stage, prs2.stage);
    swap_mem(prs1.age, prs2.age);
    swap_mem(prs1.name, prs2.name);
}

Для того, чтобы возвращать ссылку на структуру необходимо использовать функцию возвращающую ссылку. Такой тип функции мы ещё не рассматривали. В теле такой функции можно производить любые допустимые операции с данными, переданными по ссылке (или иным образом), но возвращать такая функция будет не значение, а ссылку на измененный объект. Как реализовать такую функцию показано в программе cpp-17.3. В этой программе реализована функция для перевода учащегося в старшую группу.

Программа cpp-17.3
#include <iostream>
#include <array>
#include <string>
using namespace std;

struct student {
	double weight;
	double height;
	char stage;
	int age;
	string name;
};

student &rld_stage(student&);

int main() {
    student person1 {62, 175, 'A', 16, "Abrosimov S. I."};
   	cout << person1.stage << endl;
   	person1 = rld_stage(person1);
   	cout << person1.stage << endl;
	return 0;
}

student &rld_stage(student &old_stg) {
   old_stg.stage = old_stg.stage + 1;
   return old_stg;
}
Примеры решения задач
Вопросы
Темы сообщений
Задания А
Задания Б
Задания С
Ссылки
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Print Friendly, PDF & Email

Обсуждение закрыто.