我有麻烦连接.h和.c文件,我也读了一些关于这个问题的线程,所有这些都有点模糊,仍然我不能完全掌握它的概念,并有很多链接问题说我有bc和bh,我将在ac中使用,并且混淆是否包括bh ac和bc cuz bc本身需要知道在bh中定义的结构,我有一些功能,它的原型在bh和被定义在bc中也使用bh中的结构,我不包括bc在bc cuz,因为我知道bh更像一个接口ac,将使用bc中的功能.这里一个更清楚的例子
b.h文件
typedef struct{ int x,y; }myStruct; void funct1(myStruct); void funct2(myStruct);
b.c文件
void funct1(myStruct x) { //do something } void funct2(myStruct y) { //do something }
a.c文件
#include "b.h" int main() { myStruct x; funct1(x); funct2(y); return 0; }
在cygwin中执行命令:gcc b.c a.c -g
现在的混乱部分,我有一个链接错误,其中当b.c被编译时,它不能检测b.h中的结构和原型.所有我知道的是,b.h用于链接b.c从a.c,但是当.c被编译时,似乎b.c找不到其结构和原型,
为什么我没有在b.c中包含b.h?
答案:Cuz是我所知道的,bh已经包含在ac中,当我再次包含在bc中时,我会做双重包含,这就是我迄今为止学到的东西,我知道有#ifdef,但是似乎不行,也许我还是不知道如何使用它,如果你知道,请随时讨论这一点.
如果你有任何想法,如何去,这个自由告诉我一些.
有一个#ifdef指令,但我似乎没有任何想法如何做到这一点.
解决方法
你确实需要#include b.h在b.c.每个文件在链接器接管之前都是单独编译的,所以在a.c中包含b.h并不重要,因为b.c是自己编译的,除非你包含它,否则不知道b.h的内容.
这是一个#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是常见的做法,以确保项目中的唯一性.我喜欢使用我的项目或命名空间的名称,以减少与其他代码冲突的风险.
注意:同样的头文件可以多次包含在你的项目中,即使在上面的包围守卫中,它也不能在同一个编译单元中包含两次.这说明如下:
// 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 <iostream> 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 <iostream> int getTest2(); // forward declaration int main() { std::cout << test1; std::cout << getTest2(); };