Инициализация в стеке
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 14 из 61.
Не каждому объекту нужно находиться в куче. Если struct небольшой и имеет короткий срок жизни, выделять его в стеке проще и быстрее: никаких malloc, никаких free и никакого риска утечек памяти.
Вместо возврата указателя фабричная function может вернуть структуру по значению. Вся структура копируется вызывающему коду:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Вызывающая сторона получает полностью инициализированную копию:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Никаких указателей, очистка не требуется. Когда origin и cursor выходят из области видимости, они автоматически уничтожаются.
Этот подход лучше всего подходит для небольших структур без динамически выделяемых членов. Для более крупных объектов или объектов, содержащих указатели на память в куче, шаблон конструктора с malloc остаётся лучшим выбором.
Задание
ЛегкоДавайте создадим модуль Temperature, который создаёт показания температуры в стеке с использованием фабричной функции. В отличие от конструкторов на основе кучи из предыдущих уроков, этот подход возвращает структуру по значению: без malloc, без free — только простое и эффективное выделение памяти в стеке.
Вы создадите три файла:
temperature.h: Объявите структуруTemperatureс двумя членами:double celsiusиchar scale(для хранения 'C' для шкалы Celsius). Также объявите две функции:create_temperature: принимает значение типа double и возвращает структуруTemperatureпо значению (не указатель!)temperature_to_fahrenheit: принимаетconst Temperature *и возвращает эквивалентную температуру в Fahrenheit в виде double
TEMPERATURE_H.temperature.c: Implement обе функции. Ваша фабричная функция должна создать локальную переменнуюTemperature, инициализировать её поля (установить дляscaleзначение'C') и вернуть её. Формула преобразования:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Используйте фабричную функцию, чтобы создать показание температуры и вывести значения Celsius и Fahrenheit.
Вы получите один входной параметр: температуру в Celsius (как double).
В основном файле используйте create_temperature, чтобы создать структуру Temperature с заданным значением. Затем выведите исходное значение Celsius и его эквивалент в Fahrenheit.
Выведите результат в следующем формате:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Используйте %.2f для обоих значений, чтобы отображать два знака после запятой.
Например, при вводе 25.0 результатом будет:
Celsius: 25.00
Fahrenheit: 77.00Обратите внимание, насколько чистым является этот подход. Вы получаете полностью инициализированную структуру без необходимости управлять памятью. Когда ваша переменная Temperature выходит из области видимости, она автоматически очищается.
Попробуйте сами
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Используйте create_temperature для создания структуры Temperature
// TODO: Выведите значение в градусах Цельсия, используя формат %.2f
// TODO: Используйте temperature_to_fahrenheit для преобразования и вывода значения в градусах Фаренгейта
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C