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++ 通常更合适。
  • 学这部分的重点是理解接口设计、资源所有权和回调机制。

相关:CandCpp结构体CandCpp指针进阶cpp面向对象