多代码文件:#include的作用
一、gcc -o test main.c file1.c file2.c,可否在main.c文件里面写“include file1.c"?写后,gcc命令(gcc -o test main.c file1.c file2.c)是否还需要写file1.c
1. 在 main.c 里面写 #include "file1.c" 可以吗?
技术上可以,但强烈不推荐这种做法,这是 C 语言中非常不好的习惯(bad practice)。
正确的做法应该是:
file1.h(头文件)file1.c(实现文件)
然后在 main.c 中写:
#include "file1.h"
2. 如果你真的在 main.c 里写 #include "file1.c",gcc 命令还需要加 file1.c 吗?
不需要。
因为 #include "file1.c" 会在预处理阶段就把 file1.c 的全部内容直接复制粘贴到 main.c 里面。
此时的编译情况变成:
main.c实际上已经包含了file1.c的所有代码- 所以你只需要编译
main.c即可
正确的 gcc 命令变成:
gcc -o test main.c file2.c
甚至更简单:
gcc -o test main.c file2.c
3. 为什么不建议 #include "file1.c"?
这种做法有以下严重缺点:
-
重复定义(Multiple Definition)错误
如果你在file1.c里定义了函数或全局变量,当你同时在 gcc 命令中编译main.c和file1.c时,就会出现“重复定义”错误。 -
破坏模块化设计
破坏了“.h 声明、.c 实现”的标准结构。 -
编译时间变长
每次编译main.c都会把file1.c整个重新编译一次。 -
难以维护
大型项目中会造成严重的包含混乱(include hell)。 -
无法单独编译 file1.c 做单元测试。
正确的标准写法(强烈建议)
file1.h
#ifndef FILE1_H
#define FILE1_H
void func1(void); // 函数声明
#endif
file1.c
#include "file1.h"
void func1(void)
{
// 实现...
}
main.c
#include "file1.h"
#include "file2.h"
int main(void)
{
func1();
return 0;
}
编译命令:
gcc -o test main.c file1.c file2.c
总结:
- 可以写
#include "file1.c"吗? → 可以,但非常不推荐 - 写了之后还需要把
file1.c放在 gcc 命令里吗? → 不需要 - 最好的做法:永远不要直接
#include "*.c",应该使用.h头文件 + 分开编译。
二、例子:改.c文件为“.c+.h"
1, 代码和问题
“file1.c(定义变量的地方)
#include <stdio.h>
// 定义全局变量(只定义一次)
int global_var = 100;
void print_value()
{
printf("file1.c 中的 global_var = %d\n", global_var);
}
file2.c(使用 extern 声明)
#include <stdio.h>
// 声明外部变量,告诉编译器这个变量在其他文件中定义
extern int global_var;
void modify_value()
{
global_var = 999; // 修改其他文件中的变量
printf("file2.c 修改后 global_var = %d\n", global_var);
}
main.c
#include <stdio.h>
extern void print_value(); // 声明其他文件中的函数
extern void modify_value();
int main()
{
print_value();
modify_value();
print_value(); // 再次打印,看是否被修改
return 0;
}
编译方式(Linux ):gcc -o test main.c file1.c file2.c
把file1.c文件改为.h加.c文件
2, 解决方法
很好!你目前的写法虽然能跑,但不是标准且良好的 C 语言模块化写法。
下面我给你标准、推荐的改法:把 file1.c 中的变量和函数改成使用 .h + .c 的正确结构。
正确的改法(推荐做法)
a. 新增 file1.h(头文件)
// file1.h
#ifndef FILE1_H
#define FILE1_H
// 全局变量声明(注意:这里用 extern)
extern int global_var;
// 函数声明
void print_value(void);
#endif
b. 修改 file1.c(实现文件)
// file1.c
#include <stdio.h>
#include "file1.h" // 包含自己的头文件
// 全局变量的定义(只在这里定义一次!)
int global_var = 100;
void print_value(void)
{
printf("file1.c 中的 global_var = %d\n", global_var);
}
c. 修改 file2.c
// file2.c
#include <stdio.h>
#include "file1.h" // ← 改成 include 头文件
void modify_value(void)
{
global_var = 999; // 可以直接使用,因为已在 file1.h 中 extern 声明
printf("file2.c 修改后 global_var = %d\n", global_var);
}
d. 修改 main.c
// main.c
#include <stdio.h>
#include "file1.h" // ← 改成 include 头文件
int main(void)
{
print_value();
modify_value();
print_value(); // 再次打印,看是否被修改
return 0;
}
最终的文件结构:
project/
├── main.c
├── file1.h
├── file1.c
└── file2.c
编译命令(不变):
gcc -o test main.c file1.c file2.c
或者更规范一点,加上警告:
gcc -Wall -Wextra -o test main.c file1.c file2.c
改的原因
file1.h中用extern int global_var;→ 声明(告诉其他文件有这个变量)file1.c中int global_var = 100;→ 定义(真正分配内存,只允许一次)- 其他文件(
main.c、file2.c)只需要#include "file1.h"就能使用global_var和print_value() - 避免在多个
.c文件中重复写extern - 符合业界标准的 C 程序设计习惯
提醒:
- 头文件一定要加头文件保护(
#ifndef FILE1_H…#endif),防止重复包含 - 函数建议写成
void print_value(void),明确表示没有参数 - 全局变量尽量少用,但在学习阶段这样练习是没问题的
下一步知识点: file2.c 也改成 .h + .c 的完整结构, static 变量 / 函数、模块封装
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)