2017-07-05 93 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 */ 

改为。

相关问题