多文件开发必要性
工程代码不会全部写在一个.c里,需要头文件 (.h) + 源文件 (.c) 拆分,方便模块管理、代码复用
头文件 & 源文件配对规范
- 命名:global.h ↔ global.c,名字保持一致
- 分工:
● .h头文件:放函数声明、extern 变量声明、宏、结构体定义,不要写变量定义、函数实现
● .c源文件:放函数实现、全局变量定义
头文件保护宏 #ifndef(防止重复包含)
语法模板 global.h
c
#ifndef GLOBAL_H
#define GLOBAL_H
// 这里放声明、结构体、宏
#endif
● 原理:第一次包含时GLOBAL_H未定义,执行里面代码;再次#include,因为宏已经定义,中间代码直接跳过
● 命名规范:文件名大写,点换成下划线,global.h → GLOBAL_H
● 替代写法:#pragma once,写法简单,但跨编译器兼容性不如 #ifndef,底层逆向学习推荐用#ifndef
⚠️ 易错坑: 如果直接在.h写 int g_Num;,多个 c 文件 include 这个头,每个.c 都会生成一份 g_Num,链接报重定义错误
extern 关键字(全局变量跨文件)
- extern int g_Num;:变量声明,不分配内存,告诉编译器这个变量在别的文件定义
- int g_Num = 0;:变量定义,分配内存,只能写在.c源文件
✅ 标准写法:
c
// global.h
#ifndef GLOBAL_H
#define GLOBAL_H
extern int g_Num; // 声明
#endif
c
// global.c
#include "global.h"
int g_Num = 0; // 定义,分配内存
c
// main.c
#include "global.h"
int main()
{
g_Num = 100;
return 0;
}
声明 vs 定义核心区分
| 项目 | 声明 (extern) | 定义 |
|---|---|---|
| 内存 | 不分配内存 | 分配内存 |
| 初始化 | 不能初始化 | 可以初始化 |
| 位置 | 写在.h 头文件 | 写在.c 源文件 |
总结
- 头文件只放声明,禁止变量 / 函数实现写在 h,否则多文件包含链接报错
- #ifndef 解决头文件重复包含,不是解决变量重定义;变量重定义靠extern拆分声明和定义
- #pragma once简化写法,但老编译器不支持,#ifndef兼容性最强
函数跨文件配套
函数同样:头文件写函数声明,c 文件写实现
c
//calc.h
extern void TestFunc();
c
//calc.c
void TestFunc()
{
//函数实现
}