如何包含头文件?

我在工作区中有一个带有* .c和* .h文件的普通C代码。
我有一个头文件1.h声明一些结构为

struct my1 { int a; .. .. }my_t; 

但是当我尝试在另一个头文件2.h中声明类型struct my1的变量时,如下所示: –

 struct my1 variable1; 

它在此声明点出错。

在2.h文件中看起来my1未定义。

在文件1.h中我需要包含2.h,因此在文件2.h中我不能包含1.h,因为害怕递归包含。

我的问题是: –

  1. 在这种情况下,我需要声明什么才能解决编译错误?

    这一切让我想到了有关头文件包含的更多问题。

  2. 如何包含头文件,按什么顺序,哪个头文件首先是哪一个?

  3. 递归包含头文件会导致错误一个文件包括其他包括其他包括第一个?

由于某些安全原因,无法发布实际的代码片段,如果这个问题在某种程度上会带来一些可读性问题,那就很抱歉。

您应该首先在所有.h文件中加入包含锁(这称为包含保护 ):

 #ifndef ONE_H #define ONE_H //rest of header #endif //ONE_H 

这样你可以多次包含它。

第二:

 typedef struct my1 { int a; .. .. }my_t; 

你需要一个C中的typedef(不是在C ++中)

标题按包含顺序包含在内。

如果编译一个以以下内容开头的文件abc.c:

 #include "ah" #include "bh" 

然后啊将首先包括在内,然后bh

您可以想到它,就像将代码粘贴到文件中一样。 它包括在那一点。

这就像之前的人们说的那样。

我只是想补充一点,有时即使#ifdef也无济于事。

 //file1.h #ifndef F1 #define F1 #include "file2.h" struct file1st { struct file2st *ptr; }; #endif //file2.h #ifndef F2 #define F2 #include "file1.h" struct file2st { struct file1st *ptr; }; #endif //main.c #include "file1.h" #include "file2.h" /* This will give you an error of **struct file1st not defined** Let's see why: 1) file1.h is included 2) file1.h includes file2.h before it declares anything 3) the definition of struct file2st occurs and it uses struct file1st which isn't declared yet */ int main(int argc, char* argv[]){ struct file1st st1; struct file2st st2; return 0; } 

解决这个问题的方法是:

 //file1.h #ifndef F1 #define F1 struct file2st;//just declare, it will be defined later. struct file1st { struct file2st *ptr; // ok, compiler KNOWS the size of struct file2st*(pointer) struct file2st file2Var;// NOT ok, compiler doesn't know sizeof(struct file2st) }; #endif //file2.h #ifndef F2 #define F2 #include "file1.h" struct file2st { struct file1st *ptr; }; #endif 

头文件包含在include指令的顺序中。 一旦编译器看到include指令,它就会打开要包含的文件,并简单地将其所有内容插入到包含文件中。

如果包含的文件内部包含include指令,则对它们执行相同的操作。 此过程将继续,直到处理完所有include指令。

只有在那之后才开始编译。

这就是为什么如果任何文件被包含多次(包括B和C; B和C都包括D),你会经常看到编译器抱怨重新定义。 要解决此问题,请添加包含锁 (也包括防护 ) – ifdef指令。

 //file Header1 #ifndef Header1Guard #define Header1Guard // all the header text here #endif 

我是第二个警卫的建议。

我虔诚地使用以下标题模板:

 #ifndef HELLOWORLD_H_ #define HELLOWORLD_H_ // Header stuff here. #endif // HELLOWORLD_H_ 

当编译器看到#include时,它只是用头文件的内容替换该行(减去头中任何已处理的指令)。 因此,这意味着您可以将文件包含在任意数量的位置,而不会有递归包含的风险。

每个头文件都包含在每个翻译单元(源文件)中,其中有一个include指令。 这是有意的,即使使用包含保护也会发生 – 每个使用您的结构的翻译单元都需要知道如何定义该结构,以便它可以在应用程序的所有翻译单元中以相同的方式布局在内存中。 包含防护装置只是防止它在一个翻译单元中被多次包含。 包含文件将包含在您在该翻译单元中包含它们的顺序中(如果包含文件包含其他文件,它们将被递归地包括在内……正如其他人所说的那样)。 正在编译的翻译单元的顺序由您(或您的IDE)决定,以指定编译器。 然而,这个顺序无关紧要,因为每个翻译单元都是完全独立的,直到它进入构建过程的链接阶段。

自从我和C合作以来已经有一段时间了,但我认为你想要做的是向前定义my1。

在2.h中,尝试将其置于顶部附近:

 struct my1; 

对不起,我无法回答你的其他两个问题。

 // Header1.h typedef struct tagHeader1 { } Header1; // Header2.h struct Header1; // Header2.c #include "Header1.h" 

注意:这仅适用于指针(以及c ++,引用)。 如果您有一个完整对象的引用,编译器将需要知道它。