我是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;
它给出的错误是:
数组类型具有不完整的元素类型
有人可以帮我理解是什么问题吗?
答案 0 :(得分:1)
typedef struct Vertex Vertex;
typedef struct Edge Vertex;
这可能会产生一些名称冲突,只需更改其中一个名称即可。
答案 1 :(得分:0)
唯一可行的方法是使用各种指针并解决如何实施Vertex
和Edge
结构的问题:
/*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;
为什么这样做?因为名为forward declaration的东西:
...前向声明是标识符的声明(表示 一个实体,如类型,变量或函数) 程序员还没有给出完整的定义。它是必需的 编译器以了解标识符的类型(内存大小) 分配,类型检查的类型,如函数签名), 但它不是一个特定的值(如果是变量)或 定义(在函数的情况下)......
答案 2 :(得分:0)
有人可以帮我理解是什么问题吗?
数组具有以下属性:
这允许从第一个元素的大小和内存地址以及索引id[i]
计算每个元素的内存地址(例如i
)。
为此,编译器需要知道数组元素的大小。声明Vertex::edges[20]
成员时,编译器还不知道Edge
类型的大对象有多大。因此编译错误。
避免这种情况的一种方法是,在Edge
结构之前定义Vertex
结构。在您的情况下,这没有用,因为Edge::target
的类型为Vertex
,您将收到类似的错误。结构成员的内存地址是使用对象的内存地址计算的,并添加了在请求成员之前的成员大小(可能还有一些填充)。
在这种循环依赖的情况下,可以使用指针作为成员,因为指向结构的指针具有相同的大小,无论结构具有哪个成员,指针指向。
答案 3 :(得分:0)
在此声明中
struct Vertex {
bool known;
char id[25];
Edge edges[20];
int distance;
};
尚未声明类型Edge
。这里的编译器只知道它对应于struct Edge
,但struct
本身是未知的。
答案 4 :(得分:0)
考虑一下:编译器必须知道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宏的东西,如果你想。