2015-07-19 72 views
0

我學習C以「學習C艱難的歷程」,並在運動32的宣言,我發現這個代碼在頭文件:中的C結構在頭(鏈表)

struct ListNode; 

typedef struct ListNode { 
    struct ListNode *next; 
    struct ListNode *prev; 
    void *value; 
} ListNode; 

typedef struct List { 
    int count; 
    ListNode *first; 
    ListNode *last; 
} List; 

我問題是,爲什麼作者寫:

struct ListNode; 

,然後繼續的typedef:

typedef struct ListNode { 
    struct ListNode *next; 
    struct ListNode *prev; 
    void *value; 
} ListNode; 

是否有之前DEF聲明結構的一個原因在一個typedef?

+0

在閱讀「學習難題」時,應該意識到[它被某些人認爲是不好的資源](http://www.iso-9899.info/wiki/Main_Page#Stuff_that_should_be_avoided)。也可以在該網站上找到指向被認爲「可接受」的材料的書籍鏈接和參考。如[此處所示](http://www.iso-9899.info/wiki/Snippets#Defining_a_structure_that_has_a_pointer_member_to_its_own_type),您實際上可以在'struct ListNode {ListNode * next;}之前使用'typedef struct ListNode ListNode; ListNode * prev; void * value; };'也完全可以。 –

+0

您的鏈接將幫助我很多。謝謝 –

回答

4

有些人因爲不明原因或者因爲編碼標準要求這樣做。沒有實際需要(和IMO一樣,這使得代碼不易讀,因爲它增加了無用的冗餘)。

對於typedef struct ListNode,這已經作爲不完整類型的前向聲明struct ListNode

對於第二typedef,該結構標記(struct List秒部分)是沒有多大用處的,因爲你不需要預先聲明,將可能只使用typedef編輯別名以後。

你也可以完全沒有typedef並在代碼中使用struct ListNode/struct List。我的個人意見是在任何地方都使用typedef,但我也會接受前者的一致使用。我不會混淆兩者,因爲這會導致混淆(「我是否必須爲此類型添加struct?」)。

+0

我認爲作者聲明這些結構用於實現一個LinkedList,我不知道爲什麼第二個結構是無用的。 –

+0

+1,但是你的最後一段有點不清楚,你的意思是'typedef struct List'中的'List'這個名字是沒用的嗎? – Purag

+1

@Purag:是的,struct標記沒什麼用處。我希望編輯更清楚。 – Olaf

0
struct ListNode; 

這是單獨的前向聲明。舊的編譯器需要這種類型的聲明。可能與較舊的標準或不完整的標準實現相關

struct當需要循環結構聲明時,前向聲明可能很有用。

+0

但我不明白爲什麼作者不會爲第二個結構做同樣的事情? –

+2

「老」是什麼意思? AFAIR它已經與K&R C一起工作,沒有前向聲明,因爲'typedef'中的'struct ListNode'已經作爲類型的不完整聲明。 – Olaf

+0

@VanesaGarcía你是否嘗試過沒有*那個*聲明的代碼? – this