我是c编程和阅读c入门的入门读物:第5版。令我困惑的是为什么plist
作为List的指针也可以指向Node?
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;
}
答案 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;