C头中的function?

我听说您将函数原型放在头文件中,然后将函数定义放在.c文件中。 但是,这个.c文件是什么。 例如,如果你要包含一个文件“foo.h”,你会调用前面提到的.c文件“foo.c”,把函数定义放在其中,把它放在与foo.h相同的地方,并且当你尝试包含foo.h时,该函数是否会从c文件中inheritance并且该函数是否可以使用?

不,只需将.c.h放在一起并将其包含在代码中也不会神奇地延续函数的定义。

您需要将foo.c单独编译为目标文件(在Linux的情况下,它是.o文件)。 例如使用命令 –

 gcc -c foo.c -o foo.o 

现在这个foo.o需要链接到你的实际程序。 这可以通过在编译时简单地传递目标文件来完成

 gcc test.c foo.o -o test.out 

如果你没有将foo.o与程序链接,你的链接器将无法找到其中定义的函数的实现,并将抛出链接器错误 –

函数foo_function未定义引用。

头文件只是传统的。 C预处理器正在处理#include指令 ,并且编译器会看到预处理的输入(但是您可以复制并粘贴大量的C代码以获得等效的#include )。 实际上,预处理器并不关心你是否#include "foo.h"#include "foo.c" ,但后者往往是品味不佳。 使用.h后缀命名头文件只是一种(非常常见的) 约定

因此,如果您在多个源文件(技术上的翻译单元 )中包含的标题中有一个函数定义,那么该函数定义就在每个这样的翻译单元中。

然后发生什么取决于该函数定义(它应该是static甚至更好的static inline )。

实际上,您应该将标头中的函数定义限制为staticstatic inline 。 如果你没有在一个包含在几个*.c文件中的头文件中声明一个函数定义void foo(int x) { /* something */ } ,你将在链接时有多个foo错误定义。 将函数定义放在标题中的主要兴趣是启用内联(因此inline提示); 否则(通常的情况),你不需要它,你只需将函数原型放在头文件和函数定义中的一个 *.c文件中。

如果你有简短的快速运行函数,最好它们定义static inline (所以给它们的主体)在你的头文件中(当然,这会增加编译时间)。 否则,这是不值得的负担。

一些头文件可能有很长的宏(几十个物理行,除了最后以反斜杠结尾的所有物理行)扩展到函数定义。 查看sglib的示例。

请注意, inline是今天(就像register在过去十年中一样)只是对编译器的一个提示 (用于内联扩展优化),允许忽略它(同样,许多优化编译器能够内联函数而不需要任何注释,前提是它们知道被调用函数的主体)。

不要忘记启用所有警告和调试信息。 使用 GCC,可以使用gcc -Wall -Wextra -g ,也许使用-Wstrict-prototypes 。 您可以使用-H (以及使用-C -E的预处理表单)获取包含的文件。

有关详细信息,请参阅某些C 参考站点和C11标准n1570 。 阅读有关预处理的GNU cpp参考手册。