如何将C函数移动到单独的文件中?

如何将C函数移动到单独的文件中?,c,C,我开始学习C编程。我目前有一个包含很多函数的大文件。我想将这些函数移到一个单独的文件中,以便代码更易于阅读。然而,我似乎不知道如何正确地包含/编译,并且在我找到的任何在线教程中都找不到示例。下面是一个简化的示例: #include <stdlib.h> #include <stdio.h> void func1(void) { printf("Function 1!\n"); } void func2(void) { printf("Function 2!\n

我开始学习C编程。我目前有一个包含很多函数的大文件。我想将这些函数移到一个单独的文件中,以便代码更易于阅读。然而,我似乎不知道如何正确地包含/编译,并且在我找到的任何在线教程中都找不到示例。下面是一个简化的示例:

#include <stdlib.h>
#include <stdio.h>

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}

int main(void) {
  func1();
  func2();
  return 0;
}
#包括
#包括
无效功能1(无效){
printf(“函数1!\n”);
}
无效函数2(无效){
printf(“函数2!\n”);
}
内部主(空){
func1();
func2();
返回0;
}
如何将C函数移动到单独的文件中?仅供参考:我正在使用gcc

更新:这些答案非常有用,谢谢。现在看来,我的简化示例还不够好,因为我意识到我的程序无法编译的原因是因为我在函数中使用了全局变量

#include <stdlib.h>
#include <stdio.h>

int counter = 0;

void func1(void) {
  printf("Function 1!\n");
  counter++;
}

int main(void) {
  func1();
  return 0;
}
#包括
#包括
int计数器=0;
无效功能1(无效){
printf(“函数1!\n”);
计数器++;
}
内部主(空){
func1();
返回0;
}
将这些函数移动到外部文件不起作用,因为它们需要引用此全局变量:

#include <stdlib.h>
#include <stdio.h>
#include "functions.c"

int counter = 0;

int main(void) {
  func1();
  counter = 100;
  return 0;
}
#包括
#包括
#包括“functions.c”
int计数器=0;
内部主(空){
func1();
计数器=100;
返回0;
}

我怎样才能避开这个问题呢?

首先,您必须了解声明和定义之间的区别。声明告诉编译器某些东西(如函数)存在。对于函数而言,定义是实际的函数实现


因此,您要做的是将定义移动到另一个文件中,但在要调用函数的文件中添加声明。然后将这两个文件一起构建,编译器和链接器将处理其余文件。

您可以这样做

    /* func1.c */
    void func1(void) {
      printf("Function 1!\n");
    }

    /* func2.c */
    void func2(void) {
      printf("Function 2!\n");
    }

    /* main.c */
    #include "func1.c"
    #include "func2.c"

    int main ( void )
    {
    func1();
    func2();
    return 0;
    }
好的。我们开始吧

您的main.c文件

#include <stdlib.h>
#include <stdio.h>
#include "functions.h"

int main(void) {
  func1();
  func2();
  return 0;
}
void func1(void);
void func2(void);
您的functions.c文件

#include "functions.h"

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}
用以下代码编译:

gcc -o main.exe main.c functions.c

最常见的方法是将函数原型放在头文件中,将函数实现放在源文件中。例如:

功能1.h

#ifndef MY_FUNC1_H
#define MY_FUNC1_H
#include <stdio.h>

// declares a variable
extern int var1;

// declares a function
void func1(void);
#endif
职能2.h:

#ifndef MY_FUNC2_H
#define MY_FUNC2_H
#include <stdio.h>
void func2(void);
#endif
主要条款c:

#include <stdio.h>
#include "func1.h"
#include "func2.h"

int main(void) {
    var1 += 512;
    func1();
    func2();
    return 0;
}
为了便于说明,我在每个源/头对中只放置了一个函数。您可以只创建一个包含所有源文件原型的头文件,也可以为每个源文件创建多个头文件。关键是任何调用函数的源文件都需要包含一个包含函数原型的头文件


作为一般规则,您只需要包含一次头文件,这是头文件中的
#ifndef#define#endif
宏的目的。

只需将函数定义剪切并粘贴到另一个文件中,然后使用函数声明创建一个头文件。您需要将此头包含到使用
main()
的文件中。您现在需要通过编写类似于
gcc-o program main.c functions.c
的东西来编译和链接每个源文件。请参阅:和以获取相关信息。谢谢@jonathanleffler我想我还应该指出以前的调用,它主要关注变量而不是函数,但也包含(很多)信息,很多都很有用。很有趣……这也很有效(不需要头文件)。为什么?-1:对不起,但是…在某些情况下包括
.c
源文件是可行的,但在大多数情况下是不明智的。(它在这里工作,但即使工作也不能推荐。)具体来说,如果您有两个文件,
main.c
aux.c
(同一程序的一部分),这两个文件都需要使用
func1()
func2()
,则不能在这两个文件中使用此技术。您需要一个头来声明至少在一个文件
main.c
aux.c
中使用的函数。当然,您应该有标题并将其包含在所有源文件中(
main.c
aux.c
func1.c
func2.c
)。感谢提供完整的示例。如果我只需要
#包含“functions.c”
,那么创建头文件似乎是不必要的。为什么我要创建头文件?之所以要创建头文件,是因为通常使用函数的源文件不止一个(还有
main.c
还有
aux.c
和…),而且它们不能全部使用
\include“func1.c”
技巧;只有一个源文件可以这样做,但是其他的源文件仍然需要函数声明,所以您需要一个头文件。是的。但是,包含头文件是一种很好的做法,这样您的全局声明都会出现,代码看起来也很好。ans也同意Jonathan Leffler的观点。@user1940987包含头文件是一个好主意,但是,让头文件包含源文件是不好的,因为这样做违背了创建单独头文件的目的。在您的示例中,在函数定义之后包含函数原型,这在大多数情况下甚至使创建函数原型变得毫无意义。谢谢!我添加了一个提到全局变量的更新。我将如何处理这些问题?请注意,无论是
func1.h
还是
func2.h
都不需要包含
,以使文件中的声明得以编译,因此应该省略嵌套的include。标题应该是幂等的(就像你的一样,因为标题保护)并且是自包含的。您的标题也是自包含的,但它们包含不必要的标题,这是次优的。请参阅@JonathanLeffler虽然从技术上讲是正确的,但我发现最好包含预处理新头所需的头文件,而不是要求调用它的源文件这样做。一个很好的例子是包括stdint.h以使用特定的宽度类型,如uint32_t和uint64_t。如果标头中的函数使用
中的类型,则应在标头中包括
。你的头应该
#include "func1.h" // included in order to use var1
#include "func2.h"
void func2(void) {
    printf("Function 2 with var1 == %i\n", var1);
}
#include <stdio.h>
#include "func1.h"
#include "func2.h"

int main(void) {
    var1 += 512;
    func1();
    func2();
    return 0;
}
gcc -c -o func1.o func1.c
gcc -c -o func2.o func2.c
gcc -c -o main.o  main.c
gcc -o myprog main.o func1.o func2.o
./myprog