C 语言设计
内容简介
C 语言没有类、继承和模板,但可以用结构体、函数指针、void*、宏和 C11 _Generic 模拟部分抽象能力。学习这部分的意义是理解 C 的工程组织方式,而不是强行把 C 写成 C++。
用法
用结构体和函数组织数据与行为
#include <stdio.h>
typedef struct Student {
int age;
const char *name;
} Student;
void student_print(const Student *student)
{
if (student == NULL) {
return;
}
printf("%s %d\n", student->name, student->age);
}
int main(void)
{
Student student = {18, "Alice"};
student_print(&student);
return 0;
}用函数指针实现可替换行为
typedef int (*Compare)(int, int);
int greater(int a, int b)
{
return a > b;
}
int select_by(int a, int b, Compare compare)
{
return compare(a, b) ? a : b;
}用 _Generic 做简单泛型分发
#define print_value(x) _Generic((x), \
int: print_int, \
double: print_double \
)(x)最佳代码实践
- C 中优先用“结构体 + 普通函数”组织模块,不要滥用函数指针。
- 对外暴露不完整类型和函数接口,可以模拟封装。
void*必须配合明确的类型说明和长度信息。- 宏能少用就少用;需要类型安全时优先考虑普通函数或
_Generic。
错误用法
typedef struct Student {
void (*destroy)(struct Student *self);
} Student;
void destroy(Student *self)
{
free(self->destroy); // 错误:函数指针不是 malloc 得到的内存,不能 free
}void *data;
printf("%d\n", *(int*)data); // 错误:data 未初始化,真实类型也不明确注意事项
- C 的“模拟 OOP”不等于真正的 C++ 对象模型,没有构造函数、析构函数、访问控制和虚函数机制。
- 当项目需要大量对象生命周期管理、泛型容器和类型安全抽象时,C++ 通常更合适。
- 学这部分的重点是理解接口设计、资源所有权和回调机制。