头文件包含
#include 将头文件内容插入到当前位置。头文件包含声明(函数原型、类型定义、宏),源文件包含实现。正确组织头文件是大型项目可维护性的关键。
包含方式
#include <stdio.h> /* 系统头文件,搜索系统目录 */
#include "myheader.h" /* 用户头文件,先搜索当前目录 */
头文件内容
/* math_utils.h */
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
/* 类型定义 */
typedef struct { double x, y; } Point;
/* 函数声明 */
double distance(Point a, Point b);
/* 宏定义 */
#define PI 3.14159265359
/* 内联函数(C99) */
static inline double square(double x) { return x * x; }
#endif
源文件
/* math_utils.c */
#include "math_utils.h"
double distance(Point a, Point b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(square(dx) + square(dy));
}
包含顺序
/* 推荐顺序 */
#include "当前模块头文件" /* 确保自包含 */
#include <系统头文件> /* <> */
#include "其他项目头文件" /* "" */
前向声明
/* 不需要完整定义时,用前向声明减少依赖 */
struct Node; /* 前向声明 */
void process(struct Node *node); /* 只需要指针 */
常见错误
循环包含:
/* a.h */
#include "b.h"
/* b.h */
#include "a.h" /* 循环! */
在头文件中定义变量:
/* bad.h */
int global_var; /* 每个包含的源文件都有定义 → 重复定义 */
/* 正确 */
extern int global_var; /* 声明 */
/* 一个源文件中定义 */
int global_var = 0;
最佳实践
- 头文件只放声明,不放定义(
inline和static除外) - 头文件自包含(包含它需要的所有头文件)
- 用前向声明减少依赖
- 避免循环包含
- 头文件保护防止重复包含