老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>
C语言函数一定要在.h文件中声明吗
- 前言
- 一、三种情况下的函数声明与定义策略
- 单文件小练习
- 多文件工程
- 需要在多个文件调用的函数
- 不需要跨文件调用的函数
- 二、示例
- 需要在多个文件调用的函数:
- 不需要跨文件调用的函数:
- 总结
前言
最近碰到个好问题, C语言函数一定要在.h文件中声明吗?
之所以说这是好问题, 因为它引发了一个工程问题, 如何组织函数代码文件.
这是一个非常必要理解的问题, 当涉及一个软件工程, 需要编写无数的文件, 如果不理解声明与定义分离, 很容易出bug.
一、三种情况下的函数声明与定义策略
单文件小练习
无需考虑, 用不用头文件单独声明都是可以的.
多文件工程
则需要组织文件, 情况比较复杂
需要在多个文件调用的函数
定义在C文件, 声明在.h文件
在没有定义函数的C文件中, 通过include头文件, 可以调用函数, 这个简单.
不需要跨文件调用的函数
定义在C文件, 声明.h文件, 或不声明.h文件都可以
但如果不在.h文件中声明, 那么.c文件中函数的相互调用, 一定要遵循先后顺序
通常也会先在最开始统一声明, 最后进行定义, 防止某个函数调用一个在其定义以后才声明的函数, 这个是不合法的.
对于非跨文件的函数, 请务必使用static关键字, 以防全局名称污染
二、示例
需要在多个文件调用的函数:
func.h
void func();
func.c
#include "func.h"
void func()
{语句...}
needFunc.c 需要引用func.h的C文件
#include "func.h"
void otherFunc()
{
func(); // 调用func()
语句...
}
这里的声明定义分离是十分必要的,
otherFunc()函数要调用func()函数, 有两种方式,
第一, 引入含func()函数声明的头文件
第二, 直接在needFunc.c文件中声明, 这种方式很笨, 而且文件多了容易出错.
不需要跨文件调用的函数:
func.h
void func1();
void func2();
func.c
#include "func.h"
int main()
{
func2();
}
void func1()
{语句...}
void func2()
{
func1();
语句...
}
这里函数的声明和定义分开, 虽然func2()是需要调用func1()的, 但由于声明在func.h中, 所以实现的顺序是可以随意的,
也就是说, 无论是.h文件还是.c文件, 两个函数位置可以交换.
如果没有.h文件, 则可在.c文件中最开始进行函数的声明, 后面进行定义, 这个也是OK的,
如果仅仅在.c中直接定义, 那么函数的顺序则必须是func1()定义, 然后func2()定义, 否则func2()找不到func1()
对于大多数情况, 是一个.c文件中, 既有跨文件函数定义, 也有非跨文件函数定义,
比如, func1()仅仅是服务于func2(), func2()则被其它文件调用,
那么, 可以将func2()声明在.h中, func1()声明在.c中, 并加上static修饰,
func.h
void func2();
func.c
#include "func.h"
static void func1()
{语句...}
void func2()
{
func1();
语句...
}
这样func1()的作用域仅在此.c文件中, 不会干扰全局, 其它文件声明定义同样名为func1()的函数就不会出问题, 毕竟项目大了, 不好说函数不重名.
总结
一般教材, 对于文件的组织可能一笔带过, 对于初学者, 进行单文件小练习, 完全不重要, 所以被忽视, 一旦涉及到多文件, 自己实现库供其他人调用, 则文件组织就成了必修项目.
老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>