源文件和头文件的分工
编译器会单独变异每一个模块源文件(.c文件),并一一为之生成一个唯一的目标文件。这一编译过程是与外界完全隔离的——即便模块源文件中通过“#include”方法包含了别的模块接口描述,并使用了相关的接口函数和接口变量,编译器在编译当前模块时也并不会去真正核实这些信息,可谓“两耳不闻窗外事,一心只‘译’圣贤书”。为了避免一个模块接口文件在同一个模块源文件中被重复包含,可以在头文件的开头处加入条件编译代码。
如果在头文件中放入了某个函数的代码实体,这一部分代码将随着接口描述文件一起被绑定到每一个包含了该头文件的的模块源文件中参与编译。在最后,编译器整合所有目标文件时,会发现存在多个同名的函数实体,因而产生编译错误。
头文件的循环包含会出现问题。模块分层结构下的头文件包含:在某一个层次内,我们应该使用全局包含论,层次内所有的模块通过一个统一的头文件来配置和包含,实现层次内部模块间,随时随地访问层次内部的接口函数和变量;在层次间,我们强调极端封装论:层次与层次之间不允许出现深入某一层内部直接调用某一个模块的现象,工程中任何其他位置如果想要使用某一层次中某个模块的功能,只能通过访问包含该层次的"总领头文件"来实现。