1、头文件中适合放置接口的声明,不适合放置实现(只用函数声明,不要具体实现);
2、头文件应当职责单一(一个头文件实现简单的统一的功能,功能过大,责任过多,可能要包含好多头文件,当程序加载时,要加载每个包含的头文件,会导致编译时间过长);
3、头文件的包含关系是一种依赖,一般来说,应当让不稳定的模块依赖稳定的模块,从而当不稳定的模块发生变化时,不会影响(编译)稳定的模块;
4、每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口;
5、禁止头文件循环依赖,当头文件循环依赖时,改动其中一个,所有的头文件都要重新编译;
6、.c/.h文件禁止包含用不到的头文,节省编译时间;但头文件应当自包含,不能在使用对应的.c文件时,还需要添加别的.h文件才能;编译通过;
7、为每个文件配置一个宏,当头文件第一次被包含时就定义这个宏,并在头文件被再次包含时使用它以排除文件内容
假定VOS工程的timer模块的timer.h,其目录为VOS/include/timer/timer.h,应按如下方式保护:
#ifndef VOS_INCLUDE_TIMER_TIMER_H#define VOS_INCLUDE_TIMER_TIMER_H
...
#endif
1)保护符使用唯一名称;
2)不要在受保护部分的前后放置代码或者注释;
3):头文件的版权声明部分以及头文件的整体注释部分(如阐述此头文件的开发背景、使用注意事项等)可以放在保护符(#ifndef XX_H)前面。
8、禁止在头文件中定义变量,在头文件中定义变量,将会由于头文件被其他.c文件包含而导致变量重复定义。
9、只能通过包含头文件的方式使用其他.c提供的接口,禁止在.c中通过extern的方式使用外部函数接口、变量。
10、包含标准库头文件用尖括号<>,包含非标准库头文件用双引号“”
建议:
1、一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名。为方便外部使用者,建议每一个模块提供一个.h,文件名为目录名。需要注意的是,这个.h并不是简单的包含所有内部的.h,它是为了模块使用者的方便,对外整体提供的模块接口。
2、如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。降低接口使用者的编写难度
3、头文件不要使用非习惯用法的扩展名,如.inc;使用.inc还导致source insight、Visual stduio等IDE工具无法识别其为头文件,导致很多功能不可用,如“跳转到变量定义处”。虽然可以通过配置,强迫IDE识别.inc为头文件,但是有些软件无法配置,如Visual Assist只能识别.h而无法通过配置识别.inc。
4、同一产品统一包含头文件排列方式;常见的包含头文件排列方式:功能块排序、文件名升序、稳定度排序;建议将不稳定的头文件放在前面,某一.h文件较为频繁更改,如果有错误,则不会编译其下面的头文件,可以减少编译时间;