Лабораторная работа №2. Функции, ссылки и многофайловая программа
Цель занятия: научиться проектировать функции, передавать результаты по ссылке, разделять объявления и определения и проверять функции модульными тестами.
Необходимые темы и конструкции C++:
- объявление и определение функций, перегрузка, аргументы по умолчанию
- передача по значению, ссылке и константной ссылке
- заголовочные и исходные файлы, стражи включения
- пространства имён и этапы сборки
- модульные тесты для функций со скалярными параметрами
Структура проекта
Разместите решение в следующих файлах:
main.cppfunctions.hfunctions.cpptests.cpp
Общие требования
- Соблюдайте указанные сигнатуры функций: ввод и вывод организуйте в
main. - Проверьте каждую функцию не менее чем на трёх наборах данных, включая граничный случай.
- Не используйте средства, которые не перечислены в разделе необходимых тем, если условие прямо их не разрешает.
Основные задания
-
Геометрические функции
Реализовать функции для вычисления квадрата числа, длины отрезка на числовой прямой и расстояния между двумя точками. Разместить объявления в заголовочном файле, определения — в исходном.
Требуемая сигнатура:
double square(double x); double segment_length(double a, double b); double distance(double x1, double y1, double x2, double y2);Требования:
- Для сравнения вещественных результатов в тестах используйте заданную точность.
Входные данные / вызов Результат distance(0, 0, 3, 4)5 - Площадь треугольника
Реализовать функции для проверки неравенства треугольника (\( a\leq b+c,\,b\leq a+c,\,c\leq a+b \)) (все параметры - положительные), для вычисления периметра треугольника, его площади по формуле Герона и его площади по координатам трёх его вершин и функцию, вычисляющую длины трёх высот треугольника по координатам его вершин. Формула Герона имеет следующий вид:
\[ S = \sqrt{p \cdot (p - a) \cdot (p - b) \cdot (p - c)}, \quad p = \frac{P}{2} = \frac{a + b + c}{2}. \]
Для отыскания высот треугольника создайте функциюdouble distance(double xP, double yP, double xA, double yA, double xB, double yB)вещественного типа, находящую расстояние от точки \(P(x_P, y_P)\) до прямой \(AB\), заданной точками \(A\) и \(B\) с вещественными координатами \( (x_A, y_A) \) и \( (x_B, y_B) \). Расстояние от точки до прямой считается по формуле:
\[ D(P, AB) = \frac{2 \cdot S_{PAB}}{|AB|}. \]
Функция perimeter должна проверять неравенство треугольника, используя готовую функцию. Также используем готовую функцию distance для вычисления расстояния между точками. Кроме того, вторая перегрузка функции может обращаться к первой.Требуемая сигнатура:
bool triangle_inequality(double a, double b, double c); double perimeter(double a, double b, double c); double triangle_area(double a, double b, double c); double triangle_area(double x1, double y1, double x2, double y2, double x3, double y3); void triangle_heights(double x1, double y1, double x2, double y2, double x3, double y3, double& h1, double& h2, double& h3); -
Корни уравнения через выходные параметры
Реализовать функцию решения квадратного уравнения. Возвращаемое значение — количество действительных корней: \(-1\) для бесконечного множества, \(0\), \(1\) или \(2\). Найденные корни записать в параметры-ссылки.
Требуемая сигнатура:
int solve_quadratic(double a, double b, double c, double& x1, double& x2);Требования:
- При двух корнях обеспечить
x1 < x2. - Если корней нет, значения выходных параметров не используются.
Входные данные / вызов Результат solve_quadratic(1, -3, 2, x1, x2)2; x1=1; x2=2 - При двух корнях обеспечить
-
Нормализация интервала
Функция
order_boundsменяет границы местами, если левая граница больше правой. Функцияbelongsпроверяет принадлежность числа замкнутому интервалу \([left,right]\).Требуемая сигнатура:
void order_bounds(double& left, double& right); bool belongs(double value, double left, double right);Требования:
- После вызова
order_boundsдолжно выполнятьсяleft <= right.
Входные данные / вызов Результат left=8, right=3, value=5left=3; right=8; true - После вызова
-
Сборка проекта и модульные тесты
Собрать предыдущие функции в пространстве имён
math_tasks. Подключить заголовочный файл к консольному и тестовому проектам. Для каждой функции написать тесты обычного, граничного и некорректного случая.Требования:
- В
functions.hдолжны находиться только объявления, необходимые пользователю функций. - Добавьте страж включения или
#pragma once. - Не подключайте
functions.cppдирективой#include.
- В
Домашнее задание
-
НОД и НОК
Реализовать алгоритм Евклида для наибольшего общего делителя и функцию для наименьшего общего кратного. Используйте формулу \(\operatorname{lcm}(a,b)=|a/\operatorname{gcd}(a,b)\cdot b|\).
Требуемая сигнатура:
long long gcd(long long a, long long b); long long lcm(long long a, long long b);Требования:
- Определите поведение для нулевых и отрицательных аргументов и закрепите его тестами.
Входные данные / вызов Результат gcd(-18, 24)6lcm(12, 18)36 -
Статистика цифр как библиотека
Вынести обработку цифр целого числа в функцию, которая возвращает количество цифр, а сумму и максимальную цифру передаёт через ссылки.
Требуемая сигнатура:
int digit_statistics(long long value, int& sum, int& maximum);Требования:
- Знак числа не учитывать.
- Для нуля вернуть одну цифру, сумму и максимум 0.
Входные данные / вызов Результат digit_statistics(-50730, sum, maximum)5; sum=15; maximum=7 -
Быстрое возведение в целую степень
Реализовать итерационный алгоритм возведения вещественного основания \(x\) в целую неотрицательную степень \(n\) методом последовательного возведения основания в квадрат.
Требуемая сигнатура:
double integer_power(double x, unsigned int n);Требования:
- Число умножений должно иметь порядок \(O(\log n)\).
- Функцию
std::powне использовать.
Входные данные / вызов Результат integer_power(2, 10)1024