Вспомогательные методы
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 10 из 61.
До сих пор мы рассматривали функции, которые изменяют данные структуры (такие как player_take_damage), и функции, которые просто отображают их. Но есть еще одна важная категория: функции, которые вычисляют производные значения на основе членов структуры, ничего не изменяя.
Рассмотрим структуру Rectangle, которая хранит ширину и высоту. Площадь не хранится — она вычисляется по запросу:
typedef struct {
double width;
double height;
} Rectangle;
double rectangle_area(const Rectangle *self) {
return self->width * self->height;
}
double rectangle_perimeter(const Rectangle *self) {
return 2 * (self->width + self->height);
}
Это вспомогательные методы — они берут существующие данные структуры и создают новое значение. Обратите внимание, что они используют указатели const, так как они только читают и никогда не записывают. Вычисленный результат возвращается, а не сохраняется в структуре.
Rectangle box = {5.0, 3.0};
printf("Area: %.1f\n", rectangle_area(&box)); // 15.0
printf("Perimeter: %.1f\n", rectangle_perimeter(&box)); // 16.0
Этот паттерн позволяет вашим структурам оставаться компактными — храните только необходимые данные и вычисляйте всё остальное по мере необходимости. Это также гарантирует, что производные значения всегда соответствуют текущему состоянию.
Задание
ЛегкоДавайте создадим модуль Circle, который вычисляет производные значения на основе сохраненных данных. Вы попрактикуетесь в написании вспомогательных методов — функций, которые вычисляют результаты на основе членов структуры, не изменяя их.
Вам нужно создать три файла:
circle.h: Объявите структуруCircleс единственным членомdouble radius. Также объявите два вспомогательных метода:circle_area— принимает указательconstна Circle и возвращает площадьcircle_circumference— принимает указательconstна Circle и возвращает длину окружности
CIRCLE_H.circle.c: Реализуйте оба вспомогательных метода. Для вычислений используйте3.14159в качестве значения числа пи. Формула площади —pi * radius * radius, а формула длины окружности —2 * pi * radius. Обе функции должны только считывать радиус и никогда не изменять его.main.c: Создайте Circle и используйте вспомогательные методы для вычисления и отображения его свойств.
Вы получите на вход одно значение: radius круга (в формате double).
В вашем основном файле инициализируйте Circle с заданным радиусом, затем используйте вспомогательные методы для вычисления и вывода площади и длины окружности.
Выведите результаты в следующем формате:
Area: {area}
Circumference: {circumference}Используйте %.2f для обоих значений, чтобы отобразить два знака после запятой.
Например, при радиусе 5.0 вывод будет следующим:
Area: 78.54
Circumference: 31.42Шпаргалка
Функции могут вычислять производные значения на основе членов структуры, не изменяя саму структуру. Такие функции называются вспомогательными методами (helper methods).
Вспомогательные методы используют указатели const, так как они только читают данные и никогда их не записывают:
typedef struct {
double width;
double height;
} Rectangle;
double rectangle_area(const Rectangle *self) {
return self->width * self->height;
}
double rectangle_perimeter(const Rectangle *self) {
return 2 * (self->width + self->height);
}
Использование вспомогательных методов:
Rectangle box = {5.0, 3.0};
printf("Area: %.1f\n", rectangle_area(&box)); // 15.0
printf("Perimeter: %.1f\n", rectangle_perimeter(&box)); // 16.0
Этот паттерн позволяет сохранять структуры компактными, храня в них только основные данные и вычисляя производные значения по запросу, что гарантирует их соответствие текущему состоянию.
Попробуйте сами
#include <stdio.h>
#include "circle.h"
int main() {
double radius;
scanf("%lf", &radius);
// TODO: Создайте структуру Circle с заданным радиусом
// TODO: Используйте вспомогательные методы circle_area и circle_circumference
// для вычисления и вывода результатов
// Формат вывода:
// printf("Area: %.2f\n", ...);
// printf("Circumference: %.2f\n", ...);
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга