Menu
Coddy logo textTech

Константная корректность

Часть раздела Объектно-ориентированное программирование путешествия по 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 везде, где изменение не требуется.

Эта практика помогает выявлять ошибки на раннем этапе. Если вы напишете функцию отображения и случайно измените поле, компилятор немедленно остановит вас, вместо того чтобы позволить ошибке проникнуть в вашу программу.

challenge icon

Задание

Легко

Давайте создадим модуль Temperature, который хранит значение температуры и предоставляет операции только для чтения и операции, изменяющие данные. Это поможет вам попрактиковаться в использовании указателей const, чтобы чётко различать функции, которые только читают данные, и те, которые их изменяют.

Вам нужно создать три файла:

  • temperature.h: Declare структуру Temperature с единственным членом double celsius. Также Declare три функции:
    • temp_display: принимает указатель const на Temperature и выводит текущую температуру (только для чтения)
    • temp_adjust: принимает обычный указатель на Temperature и значение типа double, затем прибавляет это значение к celsius (изменение данных)
    • temp_to_fahrenheit: принимает указатель const на Temperature и возвращает значение, преобразованное в градусы Fahrenheit (только для чтения)
    Используйте guards для включения с символом 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).

В вашем основном файле:

  1. Инициализируйте Temperature начальным значением celsius
  2. Call temp_display, чтобы вывести начальную температуру
  3. Call temp_adjust, чтобы изменить температуру на значение adjustment
  4. Call temp_display again, чтобы вывести обновлённую температуру
  5. Выведите преобразованное значение 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;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C