一直以为自己对模块化编程彻底明白了,但是偶尔看到有些条件编译感觉莫名其妙,今天一起做个总结。
1、单个功能模块建立源文件.c,和头文件.h,注意.c后缀对于C语言必须小写,有些编译器(如GCC),会认为大写C后缀是C++文件。2、对于功能模块内部使用的全局变量、函数不要放到头文件中,应该用static声明放到源文件模块的前面部分,这样做防止多文件链接的时候(编译的时候不会出错)出现函数名、变量名的重名冲突错误(即使大小写不同如int a和int A也会)。 3、对于头文件加上#ifndef xxx #define xxx啥是为了防止在同一个源文件中某个头文件被多次引用(又称包含),否则文件重复包含错误,而不是函数重复定义错误。4、对于头文件中尽量不要去定义变量,变量的定义应该放到源文件中,头文件加extern 声明即可,虽然C语言函数声明头文件中默认加extern,但为了便于理解加上extern.5、头文件中放什么合适:宏定义、类型重定义、结构体重定义以及该源文件模块需要被外部访问的函数接口、全局变量接口。6、原则上多个文件之间共享变量不在某个头文件中定义,而是采用第5条规则,源文件中定义头文件中声明,但是,UCOSII实时操作系统中有一种方法非常好,同在UCOSII.h这个头文件中定义全局数据结构来使系统其他内核文件共享这些数据结构,处理方式很巧妙。具体做法是:在头文件开头 #ifdef OS_GLOBALS
定义变量时OS_EXT OS_TCB *OSTCBCur; 而在邮箱、信号量啥源文件开头都有这样一段代码 #define OS_EXT
#else
#define OS_EXT extern
#endif #ifndef OS_MASTER_FILE
#include
#endif 唯独在Core.c文件中 #ifndef OS_MASTER_FILE #define OS_GLOBALS
#include
#endif 这么一来只有在编译Core.c文件时头文件中的数据结构编译成定义的形式,其他源文件编译成声明的形式,以后可以借鉴。 7、当头文件比较多时,每个源文件模块一个一个添加头文件方法不合理,应该定义一个头文件Config.h,然后把所有的头文件都放到这个 文件中,主要不要加防重复包含处理,只是把所有的头文件包含进去。对于便于管理可以在工程目录新建一个文件夹专门存头文件,这样的话头文件要写成#include"..\USER\Task.h",表示首先退出当前一级文件目录,然后进入USER文件夹然后找到Task.h头文件,所有的源文件、头文件中都加上 #include“Config.h”就行了,非常方便。