1. 源代码文件和头文件
大的程序一般包含(分割成)多个源代码文件(source code file),而且这些文件可能共享一些数据。可以单独编译每个文件(更一般的说法是翻译单元translation unit),再链接成最终的可执行程序。根据唯一定义规则(one definition rule,缩写odr),以函数为例,每个函数只能被定义一次,其他源代码文件需要使用已经定义过的函数时,需要输入函数原型,而函数原型可以重复出现。如果单纯地把函数原型放置(复制)到每个调用该函数的源代码文件,很容易出错,也不便于后续修改。作为替代,可以将类似函数原型的声明单独存放在一个文件中,即头文件header file,再使用#include
预编译工具把头文件包含到每个使用相应声明的源代码文件中。因此,通常把原始程序分成三个部分:
- 包含声明和原型的头文件。
- 包含函数定义(具体实现)的源代码文件。
- 包含调用函数代码的源代码文件。
头文件通常包含以下内容:
把结构体声明放到头文件中并不会创建变量,而是告诉编译器当源代码文件中声明一个该结构体类型的变量时如何创建这种结构体类型的变量。相似地,模版声明也不会被编译,而是指导编译器如何生成一个与源代码中函数调用相匹配的函数定义。
2. 应用举例
2.1 使用尖括号或者双引号包含头文件
如果头文件文件名包围在尖括号里<filename.h>
,编译器搜索文件系统中保存标准头文件的那部分;而如果包围在双引号里"filename.h"
,编译器首先搜索当前路径或者源代码文件所在路径,如果找不到,再搜索标准位置。所以标准头文件使用尖括号,自己的头文件使用双引号。
2.2 仅包含一次头文件
在一个文件中,只能包含一次头文件。为了避免多次包含头文件,通常使用一个基于预编译指令#ifndef
的标准C/C++方法,代码片段如下。这种方法并不能避免多次包含头文件,只是让编译器忽略除了第一次包含外的其他包含。
#ifndef HEADER_H_
#define HEADER_H_
// place include file contents here
#endif
分开编译代码示例5
// header file: coordin.h
#ifndef COORDIN_H_