2011-01-10 80 views
1

對不起,問這樣一個愚蠢的問題,但我真的很困惑。結構在C鏈表

struct Amit 
{ 
    int a; 
    struct Amit *link; 
} 
*start; 

這裏既有*link*start用於指向一個鏈表的節點,但什麼是這兩個之間的差異爲什麼我們不能把*start結構體內?

回答

5

link是結構類型的成員。 struct Amit類型的每個結構都有一個。

start是類型'指向struct Amit'的變量。在任何給定的時間,最多可以有一個變量,稱爲start可見。

您可以將start放在結構中,但它會成爲結構的成員(如link),並且您仍然需要聲明結構類型的變量或指向它們的指針。

這個想法是,除了最後一個列表上的每個結構都包含一個link指向列表中下一個結構的指針。通常,列表中的最後一個結構具有NULL(0)的指針link。當搜索一個列表時,你看看這些值,當你需要下一個項目時,你可以按照link的設置,當link爲NULL時停止。

struct Amit *item = start; 
while (item != NULL && item->a != value_wanted) 
    item = item->link; 

可以建立一個循環鏈表來代替它,它具有不同的停止標準。


望着意見,並解釋多一點...

來創建一個列表的方法是:

struct Amit root = { 0, NULL }; 
struct Amit *start = &root; 

變量rootroot.a == 0root.link == NULL初始化結構(或者等價地,root.link == 0)。指針變量start指向(存儲地址)root。給定一個新的節點:

struct Amit next = { 1, NULL }; 

,我們可以添加到列表的前面,其start點:

next.link = start; 
start = &next; 

一個更合理的方法來創建一個列表是通過動態分配節點,包括根節點。一致性是至關重要的,因爲你必須釋放動態分配的節點,並且動態分配一些節點,而其他節點則不是混亂的。 (我假設功能void *emalloc(size_t nbytes);malloc()一個覆蓋函數從不返回一個空指針 - 所以它的錯誤我檢查。)

// Create the empty list 
start = emalloc(sizeof(*start)); 
start->a = 0; 
start->link = NULL; 

// Create a node 
struct Amit *node = emalloc(sizeof(*node)); 
node->a = 42; 
node->link = NULL: 

// Add the node to the font of the list 
node->link = start; 
start = node; 

你通常包裝這個東西成其管理功能節點的分配,初始化和鏈接。

struct Amit *add_node(struct Amit *start, int value) 
{ 
    struct Amit *node = emalloc(sizeof(*node)); 
    node->a = value; 
    node->link = start; 
    return start; 
} 

start = add_node(start, 42); 
start = add_node(start, 30); 
start = add_node(start, 18); 

for (node = start; node->link != 0; node = node->link) 
    printf("Node: %d (%p)\n", node->a, node->link); 

等等

+0

謝謝喬納森.... – 2011-01-10 06:03:39

2

這基本上定義了三個內容:

  • 一個struct(不利用它作爲結構,順便)
  • 該結構內的成員變量,命名爲link
  • 外的可變結構名爲start

您可以通過將結構的定義從聲明中分離出來來減少混淆start變量,像這樣:

struct Amit 
{ 
    int a; 
    struct Amit *link; 
}; 

struct Amit *start; 
0

如果重命名「鏈接」到「下一個」它可以幫助你得到一個更好的感覺。一個鏈表就像一個鏈 - 你的「開始」(或者通常所說的,列表「頭」)是鏈的第一個環,鏈的下一個環通過你的「下一個」指針鏈接到它在你的情況下,你的「鏈接」指針)。當沒有其他戒指時(鏈接爲NULL),您知道鏈條上的最後一項。

0

開始點到列表頂部,並且可以在您的程序全局使用。而鏈接只是跟蹤下一個項目,並且在提及特定「節點」時可用。看到這張圖,它可以幫助你理解視覺!

鏈接在內部跟蹤下面的項目,它跟蹤下一個組件的位置,因爲它不一定與數組相鄰。

+------+  +------+  +------+ 
| data |  | data |  | data | 
+------+  +------+  +------+ 
| link |---->| link |---->| link |----> NULL 
+------+  +------+  +------+ 
^
    | 
START (Keep track of the whole list.) 

希望能幫助澄清。