类型

头文件的扩展名为.h,头文件的内容主要是函数声明和宏定义,可以被多个源文件引用。主要分为两种类型:自己编写的头文件和编译器自带的头文件。

引用

使用C语言预处理指令#include来引用头文件,引用头文件相当于复制头文件的内容,建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件。

  1. #include <stdio.h> // 引用编译器自带的头文件
  2. #include "hello.h" // 引用自己编写的头文件,在程序目录的相对路径中搜索,如果在程序目录没有找到引用的头文件则到编译器的类库路径的目录下找该头文件。

条件编译

如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误。为了防止这种情况,标准的做法是把文件的整个内容放在条件编译语句中,如下:

  1. #ifndef _HELLO_H_
  2. #define _HELLO_H_
  3. 头文件内容
  4. #endif

通过使用#ifndef包装器,当再次引用头文件时,条件为假,因为_HELLO_H_已定义。此时,预处理器会跳过文件的整个内容,编译器会忽略它。
有时需要从多个不同的头文件中选择一个引用到程序中。例如,需要指定在不同的操作系统上使用的配置参数。您可以通过一系列条件来实现这点,如下:

  1. #if SYSTEM_1
  2. # include "system_1.h"
  3. #elif SYSTEM_2
  4. # include "system_2.h"
  5. #elif SYSTEM_3
  6. ...
  7. #endif
  1. 如果头文件比较多的时候,使用宏来定义头文件的名称更简洁,这就是所谓的有条件引用。它不是用头文件的名称作为`#include`的直接参数,而是使用宏名称代替:
  1. #define SYSTEM_H "system_1.h"
  2. ...
  3. #include SYSTEM_H

小技巧

在有多个.h文件和多个.c文件的时候,往往我们会用一个global.h的头文件来包括所有的.h文件,然后在除global.h文件外的头文件中引用global.h就可以实现所有头文件的包含,同时不会乱。方便在各个文件里面调用其他文件的函数或者变量。

  1. // global.h文件
  2. #ifndef _GLOBAL_H
  3. #define _GLOBAL_H
  4. #include <fstream>
  5. #include <iostream>
  6. #include <tool.h>
  7. #include <config.h>
  8. #endif