C语言中递归头文件包含问题?

6
假设您有两个头文件中定义的相关结构,如下所示:
a.h 内容:
#include b.h

typedef struct A
{
  B *b;
} A;
b.h 内容:
#include a.h

typedef struct B
{
  A *a;
} B;

在这种情况下,递归包含是一个问题,但是两个结构体必须指向另一个结构体,如何实现这一点?
4个回答

5

不要 #include a.h 和 b.h,只需要前向声明 A 和 B。

a.h:

struct B; //forward declaration
typedef struct A
{
    struct B * b;
} A;

b.h:

struct A; //forward declaration
typedef struct B
{
    struct A * a;
} B;

您可能需要考虑类之间的耦合程度。如果它们非常紧密耦合,那么也许它们应该放在同一个头文件中。

注意:在 .c 文件中,您需要同时 #include a.h 和 b.h 来执行像 a->b->a 这样的操作。


4

Google C/C++指南建议

当只需要前向声明时,不要使用#include

这意味着:

a.h的内容:

typedef struct B B;

typedef struct A
{
  B *b;
} A;
b.h的内容:
typedef struct A A;

typedef struct B
{
  A *a;
} B;

如果您更喜欢一些比较安全的东西(但编译时间会更长),您可以这样做:
a.h 内容:
#pragma once
typedef struct A A;

#include "B.h"

typedef struct A
{
  B *b;
} A;
b.h 文件内容:
#pragma once
typedef struct B B;

#include "A.h"

typedef struct B
{
  A *a;
} B;

仅出于好奇,#pragma once是什么? - Jens Gustedt
这是一种新的方式(几乎任何编译器都支持)来完成 #ifndef MY_HEADER_H__ #define MY_HEADER_H__ ... #endif。这意味着如果你两次 #include "foo.h",而 foo.h 中有 #pragma once,它只会应用一次声明。否则你会得到一个编译错误。 - Wernight

2
你只需要预定义结构体,这样你仍然可以声明一个指针:
a.h 中:
typedef struct B_ B;

typedef struct A_
{
  B *b;
} A;

请注意我使用不同的名称来定义typedef和结构体标签,以使其更加清晰。

1

这将在C中剪切它:

typedef struct B B;
typedef struct A A;
struct A { B *b; };
struct B { A *a; };

您可以根据需要重新排列BA


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接