C语言头文件编写规则

C语言头文件编写规则---摘自《495个C语言问题》

1.存储类型extern只对数据声明有意义,对于函数声明,他可以作为格式上的提示,表明函数的定义可能在另一个源文件中,但在extern int f();和int f();之间并没有实质的区别。

2.尽管一个全局变量或函数可以(在多个编译单元中)有多处“声明(declaration)”,但是“定义(definition)”却最多只能允许出现一次。对于全局变量,定义是真正分配空间并赋初始值(如果有)的声明。对于函数,定义时提供函数体的“声明”。
例如,这些是声明:
extern int i;
extern int f();
而这些是定义:
int i=0;
int f(){
return 1;}

当希望在多个源文件中共享变量或函数时,需要确保定义和声明的一致性。最好的安排是在某个相关的.c文件中定义,然后再头.h文件中进行外部声明,在需要使用的时候,只要包含对应的头文件即可。定义变量的.c文件也应该包含该头文件,以便编译器检查定义的和声明的一致性。

这条规则提供了高度的可移植性:它和ANSI/ISO C标准一致,同时也兼顾大多数ANSI前的编译器和链接器。(unix编译器和链接器常常使用允许多重定义的‘通用模式’,只要保证最多对一处进行初始化就可以了。这种方式被ANSI C标准称为一种‘通用扩展’,没有语带双关的意思。有几个很老的系统可能曾经要求使用显式的初始化来区别定义和外部声明。)---注:这里的通用扩展在《深入理解计算机系统》中被解释成:多重定义的符号只允许最多一个强符号。函数和定义时已初始化的全局变量是强符号;未初始化的全局变量是弱符号。Unix链接器使用下面的规则来处理多重定义的符号:
规则一:不允许有多个强符号。在被多个.C源文件include的头文件里定义的全局变量会被定义多次(在预编译阶段会把头文件的信息展开在.c文件中),若在定义时显式地赋值,则违反了此规则。
规则二:如果有一个强符号和多个弱符号,那么选择强符号。
规则三:如果有多个弱符号,那么从这些弱符号中任意选择一个。

3.作为一般规则,应该把下面所列的内容放入头(.h)文件中:
a.宏定义(预处理#define);
b.结构、联合和枚举声明;
c.typedef声明;
d.外部函数声明;
e.全局变量声明;

当声明或定义需要在多个文件中共享时,把他们放入一个头文件中尤其重要。不要在两个或多个源文件的顶部重复声明或定义宏。应该把它们放入一个头文件中,然后在需要的时候用#include包含进来。这样做的原因并不仅仅是减少打字输入——这样可以保证在声明或定义变化的时候,只需要修改一处即可将结果一致地传播到各个源文件。

(特别是,永远不要把外部函数原型放到.c文件中。参见2.)

另一方面,如果定义或声明为一个源文件私有则最好留在该文件中。(作用域限于单文件的私有函数和变量应该声明为static。)
最后,不能把实际的代码(如函数体)或全局变量定义(即定义和初始化实例)放入头文件中。而且,当用多个源文件创建一个项目的时候,应该单独编译每个文件(使用特定的编译选项,只进行编译),然后用链接器将生成的目标文件链接起来。(如果是集成开发环境,这些事情可能已经不需要你自己操心了。)不要试图用#include把你的源文件“链接”成一个整体。#include是用来引入头文件而不是.c文件的。

相关文档
最新文档