C - "array type has incomplete element type"



我是C编程的新手,有以下代码。我面临以下错误。

typedef struct Vertex Vertex;
typedef struct Edge Edge;
struct Vertex {
   bool known;
   char id[25];
   Edge edges[20];
   int distance;
};
struct Edge {
   Vertex target;
   int weight;
};
typedef struct {
   Vertex Nodes[20];
   int pass;
   int infinity;
} Graph;

它给出的错误是:

数组类型具有不完整的元素类型

有人可以帮我了解问题所在吗?

typedef struct Vertex Vertex;
typedef struct Edge Vertex;

这可能会产生一些名称冲突,只需更改其中一个的名称即可。

唯一可行的方法是混合使用指针并解决如何实现VertexEdge结构:

/*your typedefs didn't make sense to me as it was conflicting. So, I edited it accordingly*/
//typedef struct Vertex Vertex;
//typedef struct Edge Vertex;
struct Vertex;
struct Edge;
typedef struct Vertex {
   bool known;
   char id[25];
   struct Edge *edges;//This HAS to be a pointer.
   int distance;
} Vertex;
typedef struct Edge {
   Vertex target;
   int weight;
} Edge;
typedef struct {
   Vertex Nodes[20];
   int pass;
   int infinity;
} Graph;

为什么会这样?因为有一种叫做前向声明的东西:

。前向声明是标识符的声明(表示 类型、变量或函数等实体),其 程序员还没有给出一个完整的定义。它是必需的 一个编译器,用于了解标识符的类型(内存大小 分配,类型检查的类型,例如函数的签名), 但不是它持有的特定值(在变量的情况下)或 定义(在函数的情况下)...

在此声明中

struct Vertex {
   bool known;
   char id[25];
   Edge edges[20];
   int distance;
};

尚未声明类型 Edge。这里的编译器只知道它将对应于一个struct Edge,但struct本身是未知的。

有人可以帮我了解问题所在吗?

数组具有以下属性:

  1. 它的所有元素都具有相同的大小。
  2. 元素是连续存储的。

这允许计算每个元素的内存地址(例如 id[i] )从第一个元素的大小和内存地址以及索引i

为此,编译器需要知道数组元素的大小。声明 Vertex::edges[20] 成员时,编译器还不知道 Edge 类型的对象有多大。因此编译器错误。

避免这种情况的一种方法是在Vertex结构之前定义Edge结构。在您的情况下,这无济于事,因为Edge::targetVertex 类型,您将收到类似的错误。结构成员的内存地址是使用对象的内存地址计算的,并添加所请求成员之前的成员的大小(可能还有一些填充)。

在这种情况下,对于循环依赖项,可以使用指针作为成员,因为无论结构具有哪个成员,指向结构的指针都具有指针指向的相同大小。

想一想:编译器必须知道顶点和边缘结构的大小。如果使 Edge 包含顶点,而 Vertex 包含 Edge,则无法真正理清大小。解决方案是只提供指向结构的指针(编译器应该知道指针大小)。我会使用带有小改动的 jrd1 版本:

struct Edge {
   struct Vertex* target;
   int weight;
} Edge;
typedef struct Vertex {
   bool known;
   char id[25];
   struct Edge edges[20];
   int distance;
} Vertex;
typedef struct {
   Vertex Nodes[20];
   int pass;
   int infinity;
} Graph;

这应该可以正常工作。

此外,如果每个边都应该将顶点指向它所在的位置,你真的不需要存储该指针,如果你愿意,你可以在 linux 内核中使用类似 container_of 宏的东西。

相关内容

最新更新