2012-04-12 165 views
2

我有這個循環依賴的問題C,我環顧了這個主題的其他問題,但實際上找不到答案。C循環依賴

我有這樣的第一個結構命名頂點:

#ifndef MapTest_vertex_h 
#define MapTest_vertex_h 

#include "edgelist.h" //includes edgelist because it's needed 

typedef struct 
{ 
    char* name; 
    float x, y; 
    edgelist* edges; 
} vertex; 

#endif 

第二結構是通過該頂點包含在EdgeList都。

#ifndef edgelist_h 
#define edgelist_h 

#include "edge.h" //include edge, because its needed 

typedef struct _edgelist 
{ 
    edge** edges; 
    int capacity, size; 
} edgelist; 

//... 

#endif 

然後最後一個結構,問題引發的結構,邊緣結構被邊界列表包含在上面。

#ifndef MapTest_edge_h 
#define MapTest_edge_h 

#include "vertex.h" //needs to be included because it will be unkown otherwise 

typedef struct 
{ 
    float weight; 
    vertex* destination; 
    int found; 
} edge; 

#endif 

我試圖盡我所能,向前聲明,使用#ifndef#define等,但未能找到答案。

我該如何解決這個循環依賴問題?

+0

在C11,你可以重複無害的typedef。你可以在任何或所有頭文件中編寫'typedef struct edge edge;''''typedef struct vertex vertex;' - 'typedef struct edgelist edgelist;'然後只需定義結構類型信息(不帶'typedef'前綴或名稱在結尾處):'struct vertex {...};' - 'struct edge {...};' - 'struct edgelist {...};'。但是這不適用於C99或C90;在早期版本的C中定義一個'typedef'是錯誤的。 – 2017-03-07 22:05:52

回答

8

似乎你應該不需要在任何文件中包含任何東西。相關類型的向前聲明應該是足夠了:

#ifndef MapTest_vertex_h 
#define MapTest_vertex_h 

struct edgelist; 

typedef struct 
{ 
    char* name; 
    float x, y; 
    edgelist* edges; // C++ only - not C 
} vertex; 

#endif 

等在C編碼,你必須寫:

struct edgelist; 

typedef struct 
{ 
    char* name; 
    float x, y; 
    struct edgelist* edges; 
} vertex; 
1

我假設一個頂點需要知道什麼邊緣連接到它,邊緣需要知道它連接的頂點。

如果是對我,我會創建單獨的數據類型的頂點和邊關聯:

struct vertex { 
    char *name; 
    float x, y; 
}; 

// edgelist as before 

struct edge { 
    float weight; 
    int found; 
}; 

// New struct to map edges and vertices 

struct vertexEdge { // you can probably come up with a better name 
    struct vertex *v; 
    struct edgelist *edges; 
}; 

// New struct to map vertices and edges 

struct edgeVertext { 
{ 
    struct edge *e; 
    struct vertex *vertices; 
}; 

我對睡眠的運行一週大約10-12小時的後面,所以我很確定有更好的方式來設計映射類型(可能不需要多於一種類型),但這是我所採用的一般方法。

2

這種依賴關係使用正向聲明中斷。相反,包括與結構的完整定義的文件,有兩種選擇:

1.

typedef struct 
{ 
    char* name; 
    float x, y; 
    struct _edgelist* edges; /* add "struct" here (elaborated type specifier) */ 
} vertex; 

2.

struct __edgelist; /* better form: forward declaration */ 

typedef struct 
{ 
    char* name; 
    float x, y; 
    struct _edgelist* edges; /* still need to add "struct" here */ 
} vertex; 
+0

請注意,以下劃線開頭並且後面跟着另一個下劃線或大寫字母的符號被無條件地保留以供'執行'使用。通常,避免創建以下劃線開頭的名稱。 – 2017-03-07 21:59:00