Willendless / willendless.github.io

My personal blog.
https://willendless.github.io
2 stars 1 forks source link

| JR's Blog #44

Open Willendless opened 3 years ago

Willendless commented 3 years ago

https://willendless.github.io/2021/02/23/2021-2-23-%E9%81%8D%E5%8E%86%E9%93%BE%E8%A1%A8%E5%B9%B6%E5%88%A0%E9%99%A4%E5%85%83%E7%B4%A0%E7%9A%84%E5%86%99%E6%B3%95/

记得有次看采访linus的视频,提到在链表中查找某个元素并删除应该采用下面的写法,而不是用前后两个指针的写法,后来在UCB上操作系统课ta在复习c语言的recitation上也提到了这个,于是就记录下来: 链表与二级指针 void remove_nodes (LinkNode *node_addr, char str) { while (node_addr != NULL) { // Iterate through list if (!strcmp((node_addr)->value, str)) { // 0 is a match LinkNode to_free = node_addr; node_addr = to_free->next; // Change the pointer free (to_free); } else { node_addr = &(node_addr)->next; // Make next changes } } } 链表的迭代如果涉及到删除请用二级指针。 首先梳理一下变量名作为一种抽象的意义,变量名本身表示一块内存空间(即一个地址)。同时所代表的空间中存储的值可以是另一个块空间的地址。 作为右值使用的时候,相当于使用变量名对应地址中的值。因此,对于上方代码。使用node_addr,相当于使用其内存储的二级指针。 作为左值使用的时候,相当于对对应的存储空间的操作。 二级指针的使用,如上例所示: 当匹配失败,将node_addr设置为指向下一个next域。因此可以发现,二级指针始终指向next域,而非整个节点,next域指向下一个节点。 当匹配成功,将当前next域的值跳过下一个设置。 二级指针的优势: 更优雅:一级指针局限于判断当前节点,如果匹配成功,需要prev指针,才能修改上一个节点。二级指针则没有这个问题。 处理边界:如果第一个节点即判断成功,则应该删除第一个节点,如果一级指针,则传入的原始一级指针最终不可用。但是二级指针会同时修改传入的一级指针,因此也没有这个问题。