Константная корректность
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 8 из 61.
При написании функций, которые действуют как методы, некоторые из них должны изменять объект (например, player_take_damage), а другие должны только читать данные, ничего не изменяя. Ключевое слово const позволяет обеспечить это различие на уровне компилятора.
Помечая параметр-указатель как const, вы обещаете, что function не будет изменять данные, на которые он указывает. Если вы случайно попытаетесь изменить member, компилятор выдаст ошибку:
typedef struct {
int x;
int y;
} Point;
// Эта функция может только ЧИТАТЬ точку
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // ERROR: нельзя изменять через указатель const
}
// Эта функция может ИЗМЕНЯТЬ точку
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
Параметр const Point *self сообщает и компилятору, и другим программистам, что point_print — это «геттер» или операция только для чтения. Это называется корректностью const: использование const везде, где изменение не требуется.
Эта практика помогает выявлять ошибки на раннем этапе. Если вы напишете функцию отображения и случайно измените поле, компилятор немедленно остановит вас, вместо того чтобы позволить ошибке проникнуть в вашу программу.
Задание
ЛегкоДавайте создадим модуль Temperature, который хранит значение температуры и предоставляет операции только для чтения и операции, изменяющие данные. Это поможет вам попрактиковаться в использовании указателей const, чтобы чётко различать функции, которые только читают данные, и те, которые их изменяют.
Вам нужно создать три файла:
temperature.h: Declare структуруTemperatureс единственным членомdouble celsius. Также Declare три функции:temp_display: принимает указательconstна Temperature и выводит текущую температуру (только для чтения)temp_adjust: принимает обычный указатель на Temperature и значение типа double, затем прибавляет это значение к celsius (изменение данных)temp_to_fahrenheit: принимает указательconstна Temperature и возвращает значение, преобразованное в градусы Fahrenheit (только для чтения)
TEMPERATURE_H.temperature.c: Implement все три функции. Функцияtemp_displayдолжна выводить данные в форматеCurrent: {celsius}C. Функцияtemp_to_fahrenheitдолжна возвращатьcelsius * 9.0 / 5.0 + 32.0. Помните, что функции, использующие указателиconst, не могут изменять данные структуры.main.c: Создайте Temperature, выполните операции и выведите результаты.
Вы получите два входных значения: начальное значение celsius (типа double) и значение adjustment (типа double).
В вашем основном файле:
- Инициализируйте
Temperatureначальным значением celsius - Call
temp_display, чтобы вывести начальную температуру - Call
temp_adjust, чтобы изменить температуру на значение adjustment - Call
temp_displayagain, чтобы вывести обновлённую температуру - Выведите преобразованное значение Fahrenheit с помощью
temp_to_fahrenheit
Выведите результаты в следующем формате:
Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}FИспользуйте %.1f для всех значений температуры, чтобы выводить один знак после десятичной точки.
Например, если начальное значение равно 20.0, а adjustment равен 5.0, результатом будет:
Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0FПопробуйте сами
#include <stdio.h>
#include "temperature.h"
int main() {
double initial_celsius, adjustment;
scanf("%lf", &initial_celsius);
scanf("%lf", &adjustment);
// TODO: Создайте структуру Temperature и инициализируйте её с initial_celsius
// TODO: Вызовите temp_display, чтобы показать начальную температуру
// TODO: Вызовите temp_adjust, чтобы изменить температуру на величину adjustment
// TODO: Снова вызовите temp_display, чтобы показать обновлённую температуру
// TODO: Выведите преобразование в Фаренгейт с помощью temp_to_fahrenheit
// Формат: "Fahrenheit: %.1fF\n"
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C