2013-11-01 31 views
6

我正在开始使用C编程。我目前有一个包含很多功能的大文件。我想将这些函数移动到一个单独的文件中,以便代码更易于阅读。然而,我似乎无法弄清楚如何正确地包含/编译,并且找不到我找到的任何在线教程中的示例。这里有一个简化的例子:如何将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; 
} 

如何将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; 
} 

移动这些功能到外部文件不起作用,因为它们需要引用这个全局变量:

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

int counter = 0; 

int main(void) { 
    func1(); 
    counter = 100; 
    return 0; 
} 

我怎样才能解决这个问题得到什么?

+0

只需将函数定义剪切并粘贴到另一个文件中,然后使用函数声明创建一个头部。您需要将此头文件包含到使用'main()'的文件中。您现在需要编译并链接每个源文件,编写诸如'gcc -o program main.c functions.c'之类的东西。 – 2013-11-01 18:26:32

+2

请参阅:[在C中使用'.h'文件的好记录模式是什么?](http://stackoverflow.com/questions/256277)和[我应该在头文件中使用'#include'吗?]( http://stackoverflow.com/questions/1804486)获取相关信息。 –

+0

谢谢@JonathanLeffler – Andrew

回答

4

首先您必须了解声明定义之间的区别。一个声明告诉编译器存在一些东西,比如一个函数。就功能而言,定义是实际的功能实现。

所以你要做的是将定义移动到另一个文件,但是在函数被调用的文件中添加一个声明。然后,您将这两个文件一起构建,编译器和链接器将负责其余部分。

+1

*一个声明告诉编译器,像一个函数,exiSts * – smRaj

+0

@smRaj谢谢,修正。 – 2013-11-01 18:29:08

+0

谢谢,很高兴知道这些条款。 – Andrew

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; 
    } 
+0

有趣...这也可以工作(不需要头文件)。这是为什么? – Andrew

+1

-1:对不起,但是......包括'.c'源文件在某些​​情况下是可行的,但在大多数情况下不合理。 (它可以在这里工作,但不能被推荐,即使它工作。)具体来说,如果你有两个文件,'main.c'和'aux.c'(同一个程序的一部分),都需要使用'func1() '和'func2()',你不能在这两个文件中使用这种技术。你需要一个头文件来声明至少在'main.c'和'aux.c'文件中使用的函数。当然,你应该有头文件并将其包含在所有源文件('main.c','aux.c','func1.c'和'func2.c')中。 –

15

好的。开始了。

的main.c文件

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

int main(void) { 
    func1(); 
    func2(); 
    return 0; 
} 

functions.h文件

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 
+0

感谢您的完整示例。似乎创建一个头文件是不必要的,如果我只能'#include“functions.c”'。为什么我会创建一个头文件? – Andrew

+0

你会创建头,因为通常你有多个使用函数的源文件(所以'main.c'也有'aux.c'和...),它们不能全部使用#include“func1.c”技巧;只有一个源文件可以做到这一点,但其他的仍然需要函数声明,所以你需要一个头文件。 –

+1

是的。但是,这是一个包含头文件的好习惯,这样你的全局声明就可以完成,代码看起来不错。人们也同意Jonathan Leffler的观点。 –

6

最常用的方法是将一个头文件中的函数原型和你的函数实现的源文件。例如:

func1.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 

func1.c

#include "func1.h" 

// defines a variable 
int var1 = 512; 

// defines a function 
void func1(void) { 
    printf("Function 1!\n"); 
} 

FUNC2。H:

#ifndef MY_FUNC2_H 
#define MY_FUNC2_H 
#include <stdio.h> 
void func2(void); 
#endif 

func2.c:

#include "func1.h" // included in order to use var1 
#include "func2.h" 
void func2(void) { 
    printf("Function 2 with var1 == %i\n", var1); 
} 

的main.c:

#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 

我只放在一个在每个源/头对中用于说明。您只能创建一个包含所有源文件原型的头文件,或者可以为每个源文件创建多个头文件。关键是任何将调用函数的源文件都需要包含一个包含该函数原型的头文件。

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

+0

谢谢!我添加了一个提到全局变量的更新。我将如何处理这些? – Andrew

+0

我已经更新了示例以使用共享的'int'变量。 –

+0

请注意,'func1.h'和'func2.h'都不需要包含''来使文件中的声明编译,因此应该省略嵌套的include。标题应该是幂等的(就像你的标题守卫一样)并且是独立的。你的设备也是独立的,但是它们包括不合理的标题。请参阅[我应该在头文件中包含吗?](http://stackoverflow.com/questions/1804486) –

相关问题