假设我们有一些C源文件,例如file1.c
,file2.c
和main.c
。我们的功能如下:
file1.c
|---> file1Func1()
|---> file1Func2()
file2.c
|---> file2Func1()
|---> file2Func2()
,主文件使用这些功能。现在,我很自然地在头文件file1.h
和file2.h
中创建和添加相应的函数原型,然后在main.c
中包含这些头以使用这些函数。
如果我有一个包含超过一千个源(C)文件的非常大的项目,我应该总是为每个源文件创建一个标题(然后添加函数原型)。然后包括使用函数的标题?
或者使用 extern 来使用在别处定义的函数(在其他一些源文件中)并依赖链接器在链接时搜索并从目标文件中获取函数?
注意:使用后一种方法会触发没有函数原型的MISRA警告。
答案 0 :(得分:7)
作为接口一部分的所有函数,即由另一个模块调用的函数,应该在头文件中具有函数原型。最好与记录如何使用该功能的评论一起使用。
不属于界面且仅在文件内部使用的函数不应在标题中包含原型。对于此类函数,请将原型声明在c文件的顶部,并将其声明为static
。
这就是所有(专业)C程序的编写方式。另外,MISRA-C也要求这种声音设计。
永远不应该有理由将extern
关键字用于函数。请注意像
void func (void);
完全等同于
extern void func (void);
如果您需要使用某个功能,请包含相关标题。
答案 1 :(得分:1)
如果我有一个包含超过一千个源(c)文件的非常大的项目,我应该总是为每个源文件创建一个标题(然后添加函数原型)。然后包括标题以使用函数?
简短的回答是“是”。
稍长的答案是“是的,但您可以省略头文件中的函数,这些函数是源文件中其他函数的实现细节”。
在头文件中声明函数并#include
头文件可确保函数定义和函数调用保持同步。否则,很容易出错,这些错误会在链接时而不是在编译时捕获。
答案 2 :(得分:0)
我应该总是创建一个标题(然后添加函数原型) 每个源文件。
TL; DR; 回答为是。
我的个人意见(以及已经写入多个公司编码标准的意见)是每个C源文件都应该有自己的关联头文件来定义外部接口。
C源文件及其关联的Header文件一起定义模块 - 但只有Header文件声明了接口。
所有全局对象(包括函数原型)都应在头文件中声明;我还提倡extern
关键字永远不应该(*)在C源文件中使用,因为这是(恕我直言)打破模块的声明接口。
{*}好吧,永远不是一个强有力的词,可能有例外......但它们应该很少而且很远。