2012-03-27 159 views
2

什麼是初始化(在本地函數)嵌套結構的長鏈當每個結構只包含指向其它結構,像這樣的最佳/乾淨的方式:初始化在C長嵌套結構

typedef struct A{ 
struct B{ 
    struct C *c /* OPTIONAL */; 
    struct D *d /* OPTIONAL */; 
    struct E *e /* OPTIONAL */; 
    struct F *f /* OPTIONAL */; 
} *b; 
struct G{ 
    struct F *f /* OPTIONAL */; 
    struct D *d /* OPTIONAL */; 
    struct H *h /* OPTIONAL */; 
    struct F *f /* OPTIONAL */; 
} *g; 
    } a; 

每個指向嵌套結構的指針都指向包含指向其他嵌套結構的指針的結構(我知道,它的瘋狂!)

我想我需要爲每個結構成員定義一個tmp指針併爲它分配內存,也是一個tmp結構變量,並將前者指向後者:

B *b_ptr = CALLOC(1,sizeof(b_ptr)); 
B b_tmp; 
b_ptr = &b_tmp; 
b_tmp.itsMember1 = CALLOC(1,sizeof(itsMember1)); 
TypeOfItsMember1 itsMember1_tmp; 
.. 
.. 

這將需要幾十個局部變量和痛苦的重複編碼。有沒有更好的方法來完全初始化父結構?

房子裏的任何專家都在照顧他們的2美分嗎?

回答

1

您可以通過編寫一組函數來分配和初始化各種嵌套結構。

struct C *NewC(int f1, int f2, ...) 
{ 
    struct C *result = malloc(sizeof(*result)); 
    result->f1 = f1; 
    result->f2 = f2; 
    ..... 
    return result; 
} 

併爲你的其他結構做同樣的事情。

然後你就可以在演唱會中使用這些構建模塊標準結構的初始化:如果你想在堆上,而不是堆棧分配你的struct B

struct B b = { 
    NewC(42, 666, ...), 
    NULL, 
    NULL, 
    NewF(....) 
}; 

,那麼你可以寫類似的靜脈NewB功能。

這種方法的優點是,如果您向結構中添加字段,只需向NewX函數添加額外參數,編譯器將強制該結構的任何客戶端提供額外參數。

+0

感謝您的回覆。我意識到我可以用所有嵌套結構的組合參數創建一個新的扁平結構,並將其引用傳遞給init函數。然後,爲每個嵌套結構分配內存,並將指針分配給創建的結構中的各個參數。 定義init函數的問題在於,有些情況下嵌套結構僅包含指向另一個結構的指針,而沒有其他內容。因此,爲此定義一個init函數沒有任何意義。無論如何,謝謝你的建議;它絕對讓我思考.. – 2012-03-28 16:04:35

1

一些可能性:

  • 採用序列化方案,這樣就可以從文件中讀取結構的圖。

  • 如果還不算太晚,可以考慮使用像Java或C++這樣的語言,以便您可以使用類和對象而不是結構。這簡化了問題,因爲每個「結構」可以自行初始化。

  • 即使無法切換到更多面向對象的語言,仍然可以使用更多面向對象的方法。通過編寫初始化每個結構和子結構的函數來解決問題。

+0

感謝您的回覆。你能指引我參考第一點嗎? – 2012-03-28 16:07:52

+0

@ user837483如果沒有任何要求,我可能會首先考慮使用XML。您可以使用[libxml2](http://xmlsoft.org/index.html)進行解析,然後您只需編寫將找到的值轉換爲結構的代碼即可。 – Caleb 2012-03-28 16:16:46