C标题中的函数?

C标题中的函数?,c,function,header,C,Function,Header,我听说您将函数原型放在头文件中,然后将函数定义放在.c文件中。但是,这个.c文件是什么。例如,如果您要包含一个文件“foo.h”,您会调用前面提到的.c文件“foo.c”,将函数定义放在其中,将其放在与foo.h相同的位置,并且当您尝试包含foo.h时,该函数是否会从c文件继承下来,并且该函数是否准备好使用?头文件只是常规的。编译器正在处理s,并且编译器会看到预处理的输入(但是您可能会复制并粘贴大量的C代码,以获得与#include等效的代码)。事实上,预处理器并不关心是否包含“foo.h”或“

我听说您将函数原型放在头文件中,然后将函数定义放在.c文件中。但是,这个.c文件是什么。例如,如果您要包含一个文件“foo.h”,您会调用前面提到的.c文件“foo.c”,将函数定义放在其中,将其放在与foo.h相同的位置,并且当您尝试包含foo.h时,该函数是否会从c文件继承下来,并且该函数是否准备好使用?

头文件只是常规的。编译器正在处理s,并且编译器会看到预处理的输入(但是您可能会复制并粘贴大量的C代码,以获得与
#include
等效的代码)。事实上,预处理器并不关心是否包含“foo.h”或“foo.c”,但后者通常是低级趣味的。使用
.h
后缀命名头文件只是一种(非常常见的)约定

因此,如果您在多个源文件(从技术上说是多个源文件)中包含的头中有一个函数定义,则该函数定义位于每个这样的转换单元中

然后发生什么取决于函数定义(它应该是
静态的
,或者更好的
静态内联的

实际上,您应该将头中的函数定义限制为
静态
静态内联
。如果不在包含在多个
*.c
文件中的头文件中声明
static
函数定义
void foo(int x){/*something*/}
,您将同时拥有多个
foo
错误定义。将函数定义放在头中的主要目的是启用内联(因此,
inline
提示);否则(通常情况下),您不需要它,只需将函数原型放在头文件中,将函数定义放在一个
*.c
文件中即可

如果您有短且快速运行的函数,那么在头文件中将它们定义为
静态内联
(因此给出它们的主体)可能是明智的(当然,这会增加编译时间)。否则,这个负担就不值了

有些头文件可能有长宏(由几十行物理行组成,除了最后一行以反斜杠结尾外,其余都是长宏)扩展为函数定义。研究一个例子

请注意,
inline
现在(就像前十年的
register
一样)只是对编译器的一个提示(用于优化),可以忽略它(而且,许多函数可以在不做任何注释的情况下内联函数,只要它们知道被调用函数的主体)

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


有关更多详细信息,请参阅一些C站点和C11标准。阅读有关预处理的手册。

头文件只是常规文件。编译器正在处理s,并且编译器会看到预处理的输入(但是您可能会复制并粘贴大量的C代码,以获得与
#include
等效的代码)。事实上,预处理器并不关心是否包含“foo.h”或“foo.c”
,但后者通常是低级趣味的。使用
.h
后缀命名头文件只是一种(非常常见的)约定

因此,如果您在多个源文件(从技术上说是多个源文件)中包含的头中有一个函数定义,则该函数定义位于每个这样的转换单元中

然后发生什么取决于函数定义(它应该是
静态的
,或者更好的
静态内联的

实际上,您应该将头中的函数定义限制为
静态
静态内联
。如果不在包含在多个
*.c
文件中的头文件中声明
static
函数定义
void foo(int x){/*something*/}
,您将同时拥有多个
foo
错误定义。将函数定义放在头中的主要目的是启用内联(因此,
inline
提示);否则(通常情况下),您不需要它,只需将函数原型放在头文件中,将函数定义放在一个
*.c
文件中即可

如果您有短且快速运行的函数,那么在头文件中将它们定义为
静态内联
(因此给出它们的主体)可能是明智的(当然,这会增加编译时间)。否则,这个负担就不值了

有些头文件可能有长宏(由几十行物理行组成,除了最后一行以反斜杠结尾外,其余都是长宏)扩展为函数定义。研究一个例子

请注意,
inline
现在(就像前十年的
register
一样)只是对编译器的一个提示(用于优化),可以忽略它(而且,许多函数可以在不做任何注释的情况下内联函数,只要它们知道被调用函数的主体)

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


有关更多详细信息,请参阅一些C站点和C11标准。阅读有关预处理的手册。

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

您需要将
foo.c
单独编译成一个对象文件(对于Linux,它是
.o
文件)。例如,使用命令-

gcc -c foo.c -o foo.o
现在需要将这个
foo.o
链接到您的实际程序。这可以通过在com运行时简单地传递对象文件来实现
gcc test.c foo.o -o test.out