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 悄悄进入程序。
挑战
简单我们来构建一个 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 类型)。
在主文件中:
- 使用初始摄氏温度值初始化一个
Temperature - 调用
temp_display显示初始温度 - 调用
temp_adjust,根据调整量修改温度 - 再次调用
temp_display显示更新后的温度 - 使用
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;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C 在线编译器