需要帮助理解C中的链表代码吗
下面是我从中获得的代码 有人能帮助理解第6行和第8行吗?如果entry->val==to_remove,则对第6行求值,*pp成为删除后的下一个条目,那么第8行在这之后做什么?当前条目已被删除,如何在第8行中重新使用此条目 另外,我知道*pp是指针pp的值,&entry->next是指针pp的地址,我总是对何时使用*和何时使用&感到困惑。具体而言,第6行可以是:需要帮助理解C中的链表代码吗,c,pointers,linked-list,double-pointer,C,Pointers,Linked List,Double Pointer,下面是我从中获得的代码 有人能帮助理解第6行和第8行吗?如果entry->val==to_remove,则对第6行求值,*pp成为删除后的下一个条目,那么第8行在这之后做什么?当前条目已被删除,如何在第8行中重新使用此条目 另外,我知道*pp是指针pp的值,&entry->next是指针pp的地址,我总是对何时使用*和何时使用&感到困惑。具体而言,第6行可以是: pp = &entry->next; 第8行是: *pp= entry->next; 若否,原因为何 &表
pp = &entry->next;
第8行是:
*pp= entry->next;
若否,原因为何
&
表示返回某物的地址*
表示访问指针指向的变量
因此,这些行:
pp = &entry->next;
*pp= entry->next;
它们是不同的
第一个指针设置为包含entry->next
的地址,而第二个指针将pp
指向的变量的值设置为等于entry->next
entry->next
在被“删除”后可以被引用的原因是,当它从链表中删除时,它仍然存在于内存中,并且仍然可以被访问。在这个示例代码中,pp存储了前一个链的“next”成员的地址,因此,如果当前链标记为要删除,则可以修改前一个链的“下一个”成员,以指向现在要删除的链的“下一个”。通过应用*运算符进行间接修改
第6行和第8行不能根据您的问题进行修改,因为这样代码将无法达到预期效果
while (entry) {
if (entry->val == to_remove)
*pp = entry->next;
else
pp = &entry->next;
entry = entry->next;
}
如果必须释放节点:
while (entry)
{
if(entry->value == to_remove )
{
*pp = entry->next;
free( entry ) ;
entry = *pp ;
}
else
{
pp = &entry->next;
entry = entry->next;
}
}
编写整个结构确实有助于理解这一点
struct Node
{
int val ;
struct Node* next ; //hint, this has an address too.
} ;
诀窍就在声明中
pp = &entry->next ;
这看起来像是指向下一个节点,但实际上只是获取当前节点指针的地址。差别很大
所以pp=&entry->next代码>几乎等同于prev=entry
从第一个示例中,唯一的区别是您指向当前结构节点的成员下一个的地址,而不是指向整个当前结构节点这里发生了什么:
list_entry **pp = &head; /* pointer to a pointer */
list_entry *entry = head;
// we start with entry being head and pp being an address of head
while (entry) {
// while there is a list_entry which is not NULL...
if (entry->val == to_remove)
// if entry points to value that should be removed,
// then store the address of the next entry in whatever pp points to now
// (which effectively means removing that entry)
*pp = entry->next; //6
// pp is now an address of the next entry
pp = &entry->next; //8
// move to the next entry to start the next iteration
entry = entry->next;
}
此代码的作用:它遍历列表并删除所有标记为已删除的条目
它是如何做到的:
- 最初,
pp
指向头部
- 从头部开始,它就在列表上方
- 每当当前条目指向的值标记为“已删除”时,
pp
将下一个列表条目的地址存储在当前列表条目的地址中。如果pp
指向头部,则表示头部被丢弃,并开始指向下一个元素。如果<代码> pp指向列表中间的一个元素,则意味着该元素被删除(因为现在的前一个元素将指向删除后的元素)。
- 完成后,它移动
条目
点以检查列表中的下一个值
entry->next是下一个节点的地址吗?它是否与“当前节点的指针地址”相同?@ericyoung&entry->next
是当前节点下一个指针的地址。我仍然不清楚:如果条目已被删除(并且可能被释放),为什么仍然可以使用当前节点的指针地址&entry->next?供您参考,还有另一个不同的实现:节点未释放意味着节点仍在链表中?你能解释一下为什么*pp=entry->next;和pp=&entry->next;在节点未释放解决方案中按原样使用,而不是按其他方式使用?我总是用错了。很抱歉,我仍然没有理解如果修改第6行和第8行,当前链将如何被跳过。你能详细解释一下吗?谢谢
list_entry **pp = &head; /* pointer to a pointer */
list_entry *entry = head;
// we start with entry being head and pp being an address of head
while (entry) {
// while there is a list_entry which is not NULL...
if (entry->val == to_remove)
// if entry points to value that should be removed,
// then store the address of the next entry in whatever pp points to now
// (which effectively means removing that entry)
*pp = entry->next; //6
// pp is now an address of the next entry
pp = &entry->next; //8
// move to the next entry to start the next iteration
entry = entry->next;
}