Лабораторная работа №3. Структуры, перечисления, пары и кортежи
Цель занятия: научиться объединять связанные данные в составные типы и возвращать из функции несколько логически связанных результатов.
Необходимые темы и конструкции C++:
struct, инициализация и доступ к полям- передача структуры по значению, ссылке и константной ссылке
enum classиswitchstd::pair,std::tuple, структурное связывание- псевдонимы типов через
using
Структура проекта
Разместите решение в следующих файлах:
main.cppmodels.hmodels.cpptests.cpp
Общие требования
- Соблюдайте указанные сигнатуры функций: ввод и вывод организуйте в
main. - Проверьте каждую функцию не менее чем на трёх наборах данных, включая граничный случай.
- Не используйте средства, которые не перечислены в разделе необходимых тем, если условие прямо их не разрешает.
Основные задания
-
Точка и отрезок
Описать структуры
PointиSegment. Реализовать вычисление длины отрезка и его середины.Требуемая сигнатура:
struct Point { double x; double y; }; struct Segment { Point begin; Point end; }; double length(const Segment& segment); Point midpoint(const Segment& segment);Входные данные / вызов Результат Segment{{0,0},{4,2}}length=4.472...; midpoint=(2,1) - Дни недели
Добавить перечисление, элементы которого соответствуют дням недели
Создать:enum class DayOfWeek { SUNDAY, MONDAY, ... }; // остальные элементы добавить самостоятельно- функцию
void showDayOfWeek(DayOfWeek dayOfWeek), которая выводит на консоль название дня недели с использованием оператораswitch; - функцию
DayOfWeek nextDayOfWeek(DayOfWeek dayOfWeek), которая возвращает следующий день недели. При этом не используйте оператор выбора, а только условные оператор и оператор явного приведения типа. Сперва идёт проверка, является ли день субботой, если да, возвращается воскресенье. Иначе переменная dayOfWeek приводится к целому числу при помощи оператора явного приведения типаstatic_cast<int>(dayOfWeek). К полученному числу прибавляется единица и результат сложения при помощиstatic_cast<dayOfWeek>()приводится к дню недели, который возвращает функция; - функцию
DayOfWeek prevDayOfWeek(DayOfWeek dayOfWeek), которая возвращает предыдущий день недели. Алгоритм работы аналогичен предыдущей функции; - функцию
bool isWeekend(DayOfWeek dayOfWeek), которая возвращает истину, если день является выходным;
- функцию
-
Вид треугольника
По трём положительным длинам сторон проверить существование треугольника и определить его вид по сторонам.
Требуемая сигнатура:
enum class TriangleKind { invalid, scalene, isosceles, equilateral }; TriangleKind classify_triangle(double a, double b, double c);Требования:
- Сначала проверьте неравенства треугольника.
- Результат выведите через отдельную функцию с
switch.
Входные данные / вызов Результат classify_triangle(5, 5, 8)isoscelesclassify_triangle(1, 2, 3)invalidЗамечание:
Помните о том, что непосредственная проверка чисел с плавающей запятой на равенство (a == b) нежелательна. Используйте константуDBL_EPSILONследующим образом:abs(a - b) < DBL_EPSILON -
Три результата измерений
Для трёх вещественных измерений вернуть минимум, максимум и среднее арифметическое в кортеже. В вызывающем коде распаковать результат структурным связыванием.
Требуемая сигнатура:
std::tuple<double, double, double> summarize(double a, double b, double c);Входные данные / вызов Результат summarize(7.5, 2.0, 5.5)min=2; max=7.5; mean=5 -
Модульные тесты
Для построенных функций (кроме
showDayOfWeek) реализуйте модульные тесты. Не менее трёх тестов для каждой.
Домашнее задание
-
Корректная дата
Описать структуру даты и функции проверки корректности и перехода к следующему дню.
Требуемая сигнатура:
struct Date { int day; int month; int year; }; bool is_valid(const Date& date); Date next_date(const Date& date);Требования:
- Для некорректной исходной даты
next_dateне вызывается.
Входные данные / вызов Результат next_date({28, 2, 2024}){29, 2, 2024} - Для некорректной исходной даты
-
Пересечение прямоугольников
Прямоугольник со сторонами, параллельными осям, задаётся координатами левой нижней и правой верхней вершин. Найти прямоугольник пересечения.
Требуемая сигнатура:
struct Rectangle { double left; double bottom; double right; double top; }; bool intersection(const Rectangle& a, const Rectangle& b, Rectangle& result);Требования:
- Касание по стороне или вершине не считать пересечением положительной площади.
Входные данные / вызов Результат {0,0,4,3}, {2,1,5,5}true; {2,1,4,3} -
Рациональное число
Описать структуру рационального числа. Реализовать нормализацию знака и сокращение дроби, сложение и сравнение двух дробей.
Требуемая сигнатура:
struct Rational { long long numerator; long long denominator; }; void normalize(Rational& value); Rational add(const Rational& a, const Rational& b); int compare(const Rational& a, const Rational& b);Требования:
- Знаменатель не должен быть равен нулю.
- После нормализации знаменатель положителен, числитель и знаменатель взаимно просты.
Входные данные / вызов Результат add({1,6}, {1,4}){5,12}