C 多文件开发

多文件开发必要性

工程代码不会全部写在一个.c里,需要头文件 (.h) + 源文件 (.c) 拆分,方便模块管理、代码复用

头文件 & 源文件配对规范

  1. 命名:global.h ↔ global.c,名字保持一致
  2. 分工:
    ● .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 关键字(全局变量跨文件)

  1. extern int g_Num;:变量声明,不分配内存,告诉编译器这个变量在别的文件定义
  2. 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 源文件

总结

  1. 头文件只放声明,禁止变量 / 函数实现写在 h,否则多文件包含链接报错
  2. #ifndef 解决头文件重复包含,不是解决变量重定义;变量重定义靠extern拆分声明和定义
  3. #pragma once简化写法,但老编译器不支持,#ifndef兼容性最强

函数跨文件配套

函数同样:头文件写函数声明,c 文件写实现

c 复制代码
//calc.h
extern void TestFunc();
c 复制代码
//calc.c
void TestFunc()
{
    //函数实现
}
相关推荐
投图匠11 分钟前
十种不同风格的 CTP接口 框架
开发语言·python
爱笑的k114 小时前
nano-vllm 源码剖析:千行 Python 手写离线推理引擎的调度、显存与并行时序
开发语言·python·vllm
X1A0RAN5 小时前
PPT 图片批量处理教程:导出全部幻灯片 · 提取全部素材
开发语言·javascript·powerpoint
熊猫钓鱼>_>6 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮6 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
布莱克6058 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
布莱克6058 小时前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型
Severus_black9 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
瑞雪兆丰年兮10 小时前
JavaWeb-day14-SpringBootWeb原理篇
java·开发语言·spring boot·spring·bean·mybatis·javaweb
唐青枫11 小时前
C 语言 strcpy() 用法详解与实战 Demo
c语言