2016-03-15 51 views
0

我的包含文件存在一個小問題,我對問題做了一個簡化的模型。 說我編譯,需要名爲轉發「Typedefing」結構

header.h 

頭文件,該文件中有一些來源:

#ifndef HEADER_INCLUDED 
#define HEADER_INCLUDED 

#include element.h 
typedef struct { 
    Element *list; 
} Thing; 

#endif 

然後我定義一個元素,也需要header.h另一頭文件。

element.h 

#ifndef ELEMENT_INCLUDED 
#define ELEMENT_INCLUDED 

typedef struct Element; 

#include header.h 
void * func(Thing *myThing); 

#endif 

然後我遇到了一個問題,因爲element.h不知道什麼類型是什麼;我們還沒有在header.h中達到這個定義,因爲我們需要包含element.h。

我想我也許可以解決我的問題爲「前進typedefing」虛空* FUNC原型樣

typedef struct thing Thing; 

前element.h展開,右一件事類型,那麼這只是創建了另一個問題,編譯器會抱怨Thing有不同的類型。

我該如何擺脫這個混亂?

+0

'typedef struct Element;'無效。你的意思是'typedef struct Element Element;'?編譯器對「Thing」的抱怨是什麼? – Potatoswatter

+0

@Patatoswatter實際上它是有效的,它和'struct Element;'意思相同; –

回答

0

最簡單的方法來解決你的問題是隔離你的結構定義在它自己的頭部,通過#ifndef /#定義像平常一樣保護。如果你不想爲這種單一結構頭文件,定義結構兩次,由其他的#ifndef /#保護其定義定義是這樣的:

#ifndef __BOOLEAN_ENUM__ 
#define __BOOLEAN_ENUM__ 
enum boolean 
{ 
    false = 0, 
    true = 1 
}; 
#endif 
1

你的主要問題是,有間循環依賴2,但你正在使用警衛宏。這些文件幾乎就像通過複製粘貼一樣包含在內 - 其中一個文件必須包含在另一個文件之前,因此您不能具有這種循環依賴關係。重新思考你的結構。

在1處聲明/定義基本數據類型,然後使用它的派生/複合數據類型,最後是將這些類型作爲參數/返回值的函數。

另外,typedef struct Element;是無效的typedef。

0

header.h不應該包括element.h。否則,你有循環依賴。

您發佈的代碼有大量錯誤。 (將來,發佈您試圖編譯的實際代碼,而不是在編輯框中進行編譯)。下面是一個例子,在這裏我省略了頭衛士爲簡潔:

// header.h 
struct Element;  // actually not necessary, but may help with readability 

typedef struct 
{ 
    struct Element *ptr; 
} Thing; 

// element.h 
#include "header.h" 

struct Element 
{ 
    int x; 
}; 

typedef struct Element Element; // optional 

void * func(Thing *myThing); 

這將有可能也將typedef struct Element Element;header.h和使用Element *ptrThing的定義裏面,它是一個你喜歡哪種方式的味道問題。有人不贊成在C語言中使用結構體的typedef,但是我喜歡它,因爲它意味着錯字會導致立即編譯錯誤,而不是靜靜地創建一個新類型。

如果您還希望element.h不依賴header.h,則可以使用與Thing相同的技術。你需要給它一個結構標籤,就像struct Element那樣。

0

從C代碼和整體程序設計的東西退步。

很明顯,「Thing」結構必須依賴於element.h中的「Element」結構。但是,從元素頭部內部使用依賴於「Thing」的函數沒有任何意義。它最有意義的是使用「Thing」的函數應該放在「Thing」標題內。

如果你用一種面向對象的方法來看待它,你不應該使用編程語言,那麼Element是一個類,Thing是一個類。該函數可以是Thing的成員函數,也可以是使用該類的非相關函數。

你會在面向對象的C中做什麼,是在它們各自的頭文件中聲明「元素」和「東西」爲不完整類型。類型定義對調用者是隱藏的,只存在於這些頭文件的相應C文件中,稱爲element.c和thing.c。處理相應類的所有成員函數將在頭文件中聲明並在C文件中定義。 (這種設計有時也被稱爲不透明類型或不透明指針。)

使用任一類的函數將包含所需的標題。