如何解决 C 中的循环结构依赖关系

How to resolve circular struct dependencies in C

所以我有两个结构,为简单起见,我们将其称为ABA 包含指向 BB[=32= 的指针] 包含一个 A。所以这是代码:

a.h

#ifndef A_H
#define A_H

#include "b.h"

typedef struct _A {
    B *b;
} A;

#endif

b.h

#ifndef B_H
#define B_H

#include "a.h"

typedef struct _B {
    A a;
} B;

#endif

现在的问题是,当我从我的主 c 文件导入 a.h 时,我从 b.h 中收到关于 A 是未知类型的错误。我不确定如何解决这个问题。

这是一个解决方案,其中 header 都不需要知道另一个 header 使用的结构标签。 (值得注意的是,B.h 中的 struct B 可以更改为 struct fooA.h 中没有任何变化。而且 A.h 根本不需要标签;struct A 可以删除。)此解决方案还允许源文件以任意顺序包含 header 或两个 header。

A.h 可以是:

#include "B.h"

#if !defined A_h
#define A_h

typedef struct A
{
    B *b;
} A;

#endif  //  #if !defined A_h

B.h可以是:

#if !defined B_h
#define B_h

typedef struct B B;

#include "A.h"

typedef struct B
{
    A a;
} B;

#endif  //  #if !defined B_h

B.h 通过执行 B 的部分(不完整)定义来工作,其中结构仅通过其标记而不是其内容已知。然后它包含 A.h 以获得有关 A 的完整信息,它仅通过指针使用 B(允许用于不完整的结构类型)。 B.h 通过完全声明 B.

结束

A.h 通过确保首先包含 B.h 来工作。它在其 header 守卫之前执行此操作,以便 B.h 中包含 A.h 将完全包含 B.h 需要的 A.h

这样做的方法是使用空定义预定义结构

typedef struct _A A;
typedef struct _B B;

typedef struct _A {
    B *b;
} A;

typedef struct _B {
    A a;
} B;

您可以将预定义放在一个全局包含文件中,以便从您需要的任何地方包含。

`

转发声明 struct _B 并删除 #incude "b.h" in a.h .

因为 a.h 只包含指向 B 的指针,所以不需要知道它的数据结构,所以在A中我们只需要声明它的名字即可。

Live sample

a.h

#ifndef A_H
#define A_H

struct _B; //forward declaration

typedef struct _A {
    struct _B* b;
} A;

#endif

b.h

#ifndef B_H
#define B_H

#include "a.h"

typedef struct _B {
    A a;
} B;

#endif

您需要了解声明和定义之间的区别。目前,我将 typedef 放在一边。为了能够做到这一点 definition:

struct A {
    struct B *b;
};

您必须首先声明 struct B。请注意,如果您在定义之前声明了某些内容,则该定义既算作定义又算作声明。但在这种情况下,由于循环依赖,我们需要单独声明。你可以解决这个问题:

struct A;
struct B;

这两行基本上是说"it exists two structs, and their names are A and B".

在大多数情况下,首选解决方案如下所示:

a.h

#ifndef A_H
#define A_H
typedef struct A A;
#endif

类似于 b.h

a.c

#include "a.h"
#include "b.h"

struct A {
    struct B* B;
};

请注意,不要对结构和类型定义使用不同的名称,除非您有充分的理由不这样做。 (我打赌你不能)如果你决定这样做,不建议以下划线开头,因为这些是为将来使用保留的。

我写了一个关于这个话题的相关回答: