2017-07-05 92 views
1

我是c編程和閱讀c入門的入門書:第5版。令我困惑的是爲什麼plist作爲指向List的指針還可以指向Node?爲什麼指向List的指針也可以指向Node?

對不起,我沒有將函數ListItemCount粘貼到代碼塊。在這個函數中,Node * pnode = *plist;,這是否意味着plist被轉換爲Node?如果是這樣,爲什麼程序需要轉換爲指向節點的指針,而不是將plist->head指定爲pnode(指向節點的指針)?

typedef struct film { 
    char title[TSIZE]; 
    int rating; 
} Item; 

typedef struct node{ 
    Item item; 
    // typical usage 
    struct node * next; 
} Node; 


/* 
* Note: to manage a linked list, we need a pointer to its beginning, 
* and we've used typedef to make List the name for a pointer of this 
* type. 
*/ 
typedef struct list{ 
    // should point to linked list Node 
    Node * head; 

    int size; 
} List; 

// TODO why `plist` as a pointer to List can also point to Node? 
/* returns number of nodes */ 
unsigned int ListItemCount(const List * plist) 
{ 
    unsigned int count = 0; 
    Node * pnode = *plist; /* set to start of list */ 
    while (pnode != NULL) 
    { 
     ++count; 
     pnode = pnode->next; /* set to next node */ 
    } 
    return count; 
} 
+1

指針可以指向任何東西。當你試圖從所述指針讀取「有意義的」數據時,事情就會出錯。如果你試圖將'List'指針轉換爲'Node'指針,你肯定會得到一些編譯器警告。 –

+0

它不能,不是真的。爲什麼你這麼想?你能詳細說明一下你會困惑嗎? –

+5

在你的代碼片段'plist'根本不使用。 – VTT

回答

0

所以你知道這是行不通的。

它應該如何工作?

Node * pnode = *plist; 

這是爲了得到第一個節點。它實際上試圖將列表類型分配爲第一個節點。爲了使它工作,我們需要將頭節點排除在外。

Node * pnode = (*plist).head; 

這現在居然返回Node* 對此更簡潔地寫:

Node * pnode = plist->head; 
1

編譯器應該對你的代碼發出警告。

但是讓我們來看看它是如何工作...

List結構的內存佈局是一樣的東西

 
+------+------+ 
| head | size | 
+------+------+ 

(上圖忽略了可能的填充。)

變量plist指向該結構的開頭:

 
+------+------+ 
| head | size | 
+------+------+ 
^ 
| 
plist 

正如您所看到的,它指向存儲head的位置。因此,通過提領plist,我們可以獲得head成員。

但它是錯誤代碼而且你不應該寫這樣的代碼。它使代碼難以閱讀,理解和維護。明確並使用

Node * pnode = plist->head; /* set to start of list */ 

改爲。

相關問題