4

我有三个文件,test.c、foo.c、foo.h。
在 foo.ci

#include "foo.h"

在 test.ci 中

#include "foo.c."  

然后当我编译我的代码时,我使用 gcc -o test test.c,它编译。

但是,我的教授告诉我,我应该使用

#include "foo.h" 

在我的 test.c 而不是里面#include foo.c,我应该这样编译它

gcc -o test test.c foo.c

第二种方式更受欢迎吗?如果是,为什么?这两个编译有什么区别?

4

7 回答 7

7

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

尽管您的教授建议的方式是正确的,但在这种情况下,以下方式具有更大的教育价值:

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

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

于 2013-02-28T15:52:40.810 回答
2

其他 .c 文件中没有 .c 文件的主要原因是#include

  • 避免重复定义错误:假设foo.c定义了函数foo()。您还有另外两个使用 的文件foo(),因此您#include "foo.c"在这两个文件中。当您尝试构建项目时,编译器将翻译foo.c多次,这意味着它将看到多次尝试定义foo函数,这将导致它发出诊断并停止。

  • 最小化构建时间:即使你没有引入重复的定义错误,你最终还是会不必要地重新编译相同的代码。假设您#include "foo.c"在 中bar.c,并且您发现需要在 中进行一行更改bar.c。当你重建时,你最终会重新翻译foo.c 不必要的内容。

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

于 2013-02-28T17:05:57.503 回答
1

通常的做法是使用#include头文件而不是源文件,并单独编译源文件。关注点分离使得在大型项目中工作更容易。在您的示例中,这可能是微不足道的,但当您有数百个文件要处理时可能会令人困惑。

按照教授建议的方式进行操作意味着您可以分别编译每个源代码。因此,如果您有一个大型项目,其中源代码是数千行代码,并且您test.c更改test.cfoo.c.

希望这有点道理:)

于 2013-02-28T15:53:01.530 回答
1

如果要在 gcc 中编译多个文件,请使用:

gcc f1.c f2.c ... fn.c -o output_file
于 2013-02-28T15:53:16.193 回答
1

简短回答:
是的,第二种方式更受欢迎。

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

于 2013-02-28T15:57:26.600 回答
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 中定义的函数

您一般将所有文件放在同一个文件夹中,编译器会找到它们并单独编译它们,稍后将通过链接器将它们连接起来。

于 2013-02-28T16:02:11.073 回答
1
gcc f1.c f2.c ... fn.c -o output_file
于 2013-03-14T01:13:34.357 回答