为什么指向List的指针也可以指向Node?

时间:2017-07-05 06:56:08

标签: c

我是c编程和阅读c入门的入门读物:第5版。令我困惑的是为什么plist作为List的指针也可以指向Node?

抱歉,我没有将函数ListItemCount粘贴到代码块中。在此函数Node * pnode = *plist;中,这是否意味着plist被转换为Node的ponter点?如果是这样,为什么程序需要转换为指向节点的指针而不是将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;
}

2 个答案:

答案 0 :(得分:1)

编译器应该针对该代码向您发出警告。

然而,让我们来看看它是如何工作的......

List结构的内存布局类似于

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

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

变量plist指向该结构的开头:

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

如您所见,它指向存储head的位置。因此,通过解除引用plist,我们可以获得head成员。

但它是 错误的代码 ,你永远不应该编写这样的代码。它使代码难以阅读,理解和维护。明确并使用

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

代替。

答案 1 :(得分:0)

所以你知道这不起作用。

它应该如何运作?

Node * pnode = *plist;

这是为了获得第一个节点。它实际上尝试将列表类型指定为第一个节点。为了使它工作,我们需要从中获得头节点。

Node * pnode = (*plist).head;

现在实际上会返回Node* 更简洁地写这个:

Node * pnode = plist->head;