使用带有#ifdef标头防护的.c文件链接.h文件

我无法链接.h和.c文件,我也阅读了一些关于这个问题的线程,所有这些都有点模糊,但我仍然无法完全掌握它的概念,并且我有很多链接问题, 说我有bc和bh,我将在ac中使用 ,我很困惑是否包括bh ac和bc cuz bc本身需要知道bh中定义的结构,我有一些function,其原型在bh中定义在bc中也使用了bh中的结构,我不知道在bc cuz中的bh,因为我知道bh更像是将使用bc中的函数的ac接口。这里有一个更清晰的例子

bh文件

typedef struct{ int x, y; }myStruct; void funct1(myStruct); void funct2(myStruct); 

bc文​​件

 void funct1(myStruct x) { //do something } void funct2(myStruct y) { //do something } 

ac文件

 #include "bh" int main() { myStruct x; funct1(x); funct2(y); return 0; } 

执行cygwin中的命令: gcc bc ac -g

现在令人困惑的部分,我有一个链接错误,其中当bc编译时,它无法检测结构和原型在bh Cuz所有我知道的是bh用于链接bc从交流,但当两个.c编译时似乎那个bc找不到它的结构和原型,

为什么我没有在bc中包含bh? :因为我知道,因为bh已经包含在交流中了,当我再次将其包含在bc中时,我会做双重包含<—这就是我到目前为止学到的东西,我知道有#ifdef但似乎它不会起作用,也许我还是不知道如何使用它,如果你知道的话请随意讨论这个。

如果你有任何关于如何去做的想法,请随时告诉我一些。

有一个#ifdef指令,但我似乎无法知道如何做到这一点。

注意:如果有任何拼写错误的单词,请假设所有上面的代码都是完全正确的,请忽略,我只是在.h和.c之后的内容之后

你确实需要在bc #include bh 。 在链接器接管之前,每个文件都是单独编译的,因此在ac中包含bh并不重要,因为bc是自己编译的,除非你包含它,否则不知道bh的内容。

这是一个#include守卫的例子

 // some_header_file.h #ifndef SOME_HEADER_FILE_H #define SOME_HEADER_FILE_H // your code #endif 

当some_header_file.h包含在任何地方时,如果定义了SOME_HEADER_FILE_H,则会忽略#ifndef#endif之间的所有内容,这将在第一次包含在编译单元中时发生。

通常的做法是在文件名后面命名#define ,以确保项目中的唯一性。 我喜欢在其前面添加我的项目或命名空间的名称,以减少与其他代码冲突的风险。

注意:即使使用上面的include guard,也可以在项目中多次包含相同的头文件,它只能在同一个编译单元中包含两次。 这表现如下:

 // header1.h #ifndef HEADER_H #define HEADER_H int test1 = 1; #endif // header2.h #ifndef HEADER_H #define HEADER_H int test2 = 2; #endif 

现在让我们看看当我们尝试包含上述两个文件时会发生什么。 在单个编译单元中:

 // a.cpp #include "header1.h" #include "header2.h" #include  int main() { std::cout << test1; std::cout << test2; }; 

这会生成编译器错误,因为未定义test2 - 它在header2.h中被忽略,因为HEADER_H已经被包含的时间定义。 现在,如果我们将每个头包含在单独的编译单元中:

 // a.cpp #include "header2.h" int getTest2() { return test2; }; // b.cpp #include "header1.h" #include  int getTest2(); // forward declaration int main() { std::cout << test1; std::cout << getTest2(); }; 

它编译得很好并产生预期的输出(1和2),即使我们包括两个定义HEADER_H的文件。

您需要在使用bh中定义的结构的所有文件中包含bh 。 所以你需要在两个文件中加上#include 。 为了避免多次加载bh ,您需要指令#ifdef 。 在你的情况下:

BH

 #ifndef B_H #define B_H typedef struct{ int x, y; }myStruct; void funct1(myStruct); void funct2(myStruct); #endif 

和bc:

 #include "bh" void funct1(myStruct x) { //do something } void funct2(myStruct y) { //do something } 

正确的编码可以包括bc中的bh

这是一个应该工作的标题后卫:

 #ifndef B_H_INCLUDED #define B_H_INCLUDED //header file #endif 

将您的声明放在评论所在的位置,并包含您需要的任何位置。

编辑我理解它的方式是, gcc首先编译bc,因为ac取决于bc但是当它首先编译bc时,bh 还没有包含在内

你需要在bc中#include bh它不仅仅是ac的接口,bc也需要知道自己代码的相同定义。 你在bc中不包括bh的原因是错误的。 每个.c文件都是与其他所有.c文件分开编译的。 当编译器完成ac时,它会以bc重新开始。无论ac包括bh都没关系,因为bc没有ac甚至存在的概念。 头文件防护的目的是防止.h文件在编译给定的.c文件时被多次包含时重复处理。 如果没有防护,声明将被多次编译,导致现有符号的多个声明出错。