2013-02-28 73 views
4

我有三个文件,test.c,foo.c,foo.h.
在我的foo.c我应该用哪种方式编译我的C代码?

#include "foo.h" 

在test.c的我

#include "foo.c." 

后来,当我编译我的代码,我用gcc -o测试test.c的,并将其编译。

然而,我的教授告诉我,我应该使用

#include "foo.h" 

我test.c的内部,而不是#include foo.c,我应该编译它这样

gcc -o test test.c foo.c 

是第二种方式更优选?如果是这样,为什么?这两个汇编有什么区别?

+0

简单就是试试:'make'命令 – 2013-02-28 16:03:38

+0

但是我想了解下make的内容。学习像C这样的低级语言的目的不是? – octref 2013-02-28 16:05:32

+0

没有[make](http://www.opussoftware.com/tutorial/TutMakefile.htm)实用程序用于编译源代码(任何语言)。 – 2013-02-28 16:09:16

回答

7

在大多数情况下,您不应该包含源文件(除了您可能希望包含由单独脚本动态生成的一段代码的情况)。源文件将被直接传递给编译器。只应包含头文件。

虽然你的教授建议的方法是正确的,下面的方式在这种情况下,更多的教育价值:

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

前两行编译每个源文件到目标文件,第三行没有按没有真正的编译,只是调用链接器生成2个目标文件中的可执行文件。这个想法是区分编译链接,这将按照你的教授建议的方式透明地执行。

+0

尽管在C++中使用'template',你必须**在头文件中包含CXX文件或直接在头文件中写入实现。这是C++的一个令人讨厌的一面。 – phoeagon 2013-02-28 15:59:57

+6

这个问题被标记为c而不是C++。 – 2013-02-28 16:02:43

+0

对不起,但是gcc -o foo.o test.o会产生什么?可执行文件名为?我可以使用gcc -o test foo.o test.o吗?除此之外,感谢您的详细解释! – octref 2013-02-28 16:09:06

1

#include代替源文件的头文件,并单独编译源文件是很常见的做法。分离顾虑使得在大型项目中工作变得更容易。在你的例子中,它可能是微不足道的,但是当你有数百个文件需要处理时可能会引起混淆。

按照您的教授所建议的方式来做,意味着您可以分别编译每个源文件。因此,如果您有一个源代码数千行的大型项目,并且您在test.c中更改了某些内容,则可以重新编译test.c,而不必重新编译foo.c

希望这有一定道理:)

1

如果你想编译GCC几个文件,使用:

gcc f1.c f2.c ... fn.c -o output_file 
1

简短的回答:
是第二种方式是更优选的。

长答案:
在这个特定的情况下,你会得到相同的结果。
要想知道你需要知道的东西,你首先需要知道“#include”语句基本上复制了它包含的文件,并把它的值而不是“#include”语句。
因此,“h”文件用于前向声明,您不会遇到几个不同文件将包含的问题。
虽然“c”文件具有实现,在这种情况下,如果两个文件都将实现相同的功能,那么在链接它们时会出现错误。
假设你将有“test2.c”,并且你还将包含foo.c并尝试将它与test.c链接起来,你将有两个foo.c的实现。但是如果你只在所有3个文件(foo.c,test.c和test2.c)中包含foo.h,你仍然可以链接它们,因为foo.h不应该有任何实现。

1

包含.c文件不是很好的做法。

在你的情况 包括用在test.c的和的foo.c foo.h中,但添加这个头文件

#ifndef foo.h 
#define foo.h 

..your header code here 


#endif 

写头以上方式中,确保您可以包括它的多个次,只是为了安全起见。

来到你必须如何把你的代码中的文件>

foo.h中

你把你所有的全球结构和变量函数原型一起,你将使用。

在foo.c的

在这里,你定义的模块化功能

在test.c的

在这里,你通常有你的main(),会让你调用并测试foo.c中定义的函数

Yo u通常将所有文件放在同一个文件夹中,编译器会找到它们并单独编译它们,稍后连接器将连接它们。

2

主要原因不能在其他.c文件#include .c文件是:

  • 避免重复定义错误:假设foo.c定义功能foo()。你有两个其他文件使用foo(),所以你在这两个文件中都是#include "foo.c"。当您尝试构建项目时,编译器会多次翻译foo.c,这意味着它会多次尝试定义foo函数,这会导致它发出诊断并暂停。尽可能减少编译时间:即使不引入重复的定义错误,也可以在不必要的情况下重新编译相同的代码。假设您在bar.c中有#include "foo.c",并且您发现需要在bar.c中进行单行更改。当您重建时,您会重新翻译不必要的foo.c的内容

C允许您分别编译源文件,然后将生成的目标文件链接在一起以构建应用程序或库。理想情况下,头文件应该只包含非定义对象声明,函数原型声明,类型定义和宏定义。

1
gcc f1.c f2.c ... fn.c -o output_file 
相关问题