Menu
CoddyTech

const 正确性

本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 8 课,共 61 课。

编写用作方法的函数时,有些函数应该修改对象(例如 player_take_damage),而另一些函数应该只读取数据,不做任何更改。const 关键字可以让你在编译器层面强制执行这种区分。

将指针参数标记为 const,就表示你承诺函数不会修改它所指向的数据。如果你不小心尝试更改成员,编译器就会报错:

typedef struct {
    int x;
    int y;
} Point;

// 这个函数只能读取该点
void point_print(const Point *self) {
    printf("(%d, %d)\n", self->x, self->y);
    // self->x = 10;  // 错误:不能通过 const 指针修改
}

// 这个函数可以修改该点
void point_move(Point *self, int dx, int dy) {
    self->x += dx;
    self->y += dy;
}

const Point *self 参数告诉编译器和其他程序员,point_print 是一个“getter”,也就是只读操作。这称为 const 正确性:在不需要修改的地方都使用 const。

这项练习能帮你尽早发现 bug。如果你编写了一个显示函数,却意外修改了某个字段,编译器会立即停止编译,而不是让 bug 悄悄进入程序。

challenge icon

挑战

简单

我们来构建一个 Temperature 模块,用来存储温度值,并提供只读操作和修改操作。这样你就能练习使用 const 指针,清楚地区分仅读取数据的函数和会修改数据的函数。

你将创建 3 个文件:

  • temperature.h:声明一个 Temperature 结构体,其中包含一个 double celsius 成员。还要声明 3 个函数:
    • temp_display:接收一个指向 Temperature 的 const 指针,并输出当前温度(只读)
    • temp_adjust:接收一个指向 Temperature 的普通指针和一个 double 类型的数值,然后将该数值加到 celsius 上(修改)
    • temp_to_fahrenheit:接收一个指向 Temperature 的 const 指针,并返回转换为华氏温度后的值(只读)
    使用符号 TEMPERATURE_H 设置包含保护。
  • temperature.c:实现这 3 个函数。temp_display 函数应按 Current: {celsius}C 的格式输出。temp_to_fahrenheit 函数应返回 celsius * 9.0 / 5.0 + 32.0。请记住,使用 const 指针的函数不能修改结构体中的数据。
  • main.c:创建一个 Temperature,执行操作并显示结果。

你会收到两个输入:初始摄氏温度值(double 类型)和调整量(double 类型)。

在主文件中:

  1. 使用初始摄氏温度值初始化一个 Temperature
  2. 调用 temp_display 显示初始温度
  3. 调用 temp_adjust,根据调整量修改温度
  4. 再次调用 temp_display 显示更新后的温度
  5. 使用 temp_to_fahrenheit 输出华氏温度转换结果

按以下格式输出结果:

Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}F

所有温度值都使用 %.1f,显示 1 位小数。

例如,初始值为 20.0,调整量为 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 在线编译器