很多.c文件和.h文件的说明都能搜到,这里主要是记录下在写代码与看源码过程中对某些用法的理解与记录
1. .h文件与.c文件各自作用,以及编译过程读取两者内容的顺序
1.1 作用
** 通常一个name.c 与一个 name.h 文件构成一个功能模块,那么 .h / .c文件应该分别放哪些内容?最常见的解释,.h放声明,.c放定义。但其实声明定义都可以放.c文件,会根据你的想法将内容分割到.h 和 .c 文件中,其中还涉及到 extern 关键字**
- 首先,.h文件中应该放 该模块愿意被其他模块见到的内容(函数,结构体声明),因为.h文件会被别的文件导入,在编译器编译预处理阶段会将 include 的.h件的内容直接完整复制到当前文件中,也就是说 .h文件中放的内容应该秉承着C语言中 “可以重复声明,但不能重复定义的原则”,只要你的.h文件内容被别的文件导入后仍然满足该原则,那么就是可行的。
- 由上面引出一个问题,如果我一个模块想暴露一个 全局变量 给别人使用,应该怎么做
-
- 法一: 变量定义到 .c文件中,其他文件要使用他直接一个 extern 就可以使用了,如:
// a.c
typedef struct {
int a;
int b;
} HandleTypeDef;
HandleTypeDef handle;
// d.h 或 d.c
extern HandleTypeDef handle;
handle.a = 1;
handle.b = 1;
-
- 上面的方法有个缺点,如果你不是写代码的人,你读到 d.h 或 d.c文件看到这个变量你根本不知道他到底定义在哪个模块的对不对。所以法二更好
-
- 法二: 变量定义到 模块.c文件中,在该模块.h文件中extern 一下, 然后使用的其他文件通过include 模块的.h文件,在.c文件使用就行,如:
// a.h
typedef struct {
int a;
int b;
} HandleTypeDef;
extern HandleTypeDef handle;
// a.c
#include a.h
HandleTypeDef handle;
/** ---------------------------------------------------------------------------------------- **/
// d.h
# include a.h
// d.c
#include d.h
handle.a = 1;
handle.b = 1;
2. 为什么在 .c文件中 include 而不在 .h文件中include
2.1 提出这个问题主要是我在CubeMX生成的main.c文件看到了include
- 经过思考 #include本质上是复制粘贴,也就是说, 如果一个模块的内容只在当前模块编写的.C文件中出现而未在 当前 编写模块的.h文件中出现,优先考虑只在.c文件中#include他,这样会减少预处理阶段的任务量,同时代码结构也比较清晰,并且对预防循环导入有一定的作用。