I want to change the world, but I can't find the source code.

想改变世界,但找不到源代码,这的确比较凄凉。但是如果源代码就在那里,只不过你没去看,那更是悲哀。

昨天在cool shell上看到一篇文章(http://coolshell.cn/articles/8990.html),主要讲述如何利用二级指针删除单向链表。代码如下:

View Code
 1 void remove_if(node ** head, remove_fn rm)
 2 {
 3     for (node** curr = head; *curr; )
 4     {
 5         node * entry = *curr;
 6         if (rm(entry))
 7         {
 8             *curr = entry->next;
 9             free(entry);
10         }
11         else
12             curr = &entry->next;
13     }
14 }

然后对比一下传统的做法:

View Code
 1 typedef struct node
 2 {
 3     struct node * next;
 4     ....
 5 } node;
 6  
 7 typedef bool (* remove_fn)(node const * v);
 8  
 9 // Remove all nodes from the supplied list for which the
10 // supplied remove function returns true.
11 // Returns the new head of the list.
12 node * remove_if(node * head, remove_fn rm)
13 {
14     for (node * prev = NULL, * curr = head; curr != NULL; )
15     {
16         node * const next = curr->next;
17         if (rm(curr))
18         {
19             if (prev)
20                 prev->next = next;
21             else
22                 head = next;
23             free(curr);
24         }
25         else
26             prev = curr;
27         curr = next;
28     }
29     return head;
30 }

差距在哪里呢?针对这两段代码来说,是1.没有认识到head指针和node->next其实是同一样东西(struct node*,指向下一个等处理的元素),2.可以统一使用二级指针来处理。再本质一点,也就是用linus大婶的话来说,不懂指针。

显然我现在还没有到懂指针的水平,可能懂指针之后就会很自然地想到,删除单向链表,其实就是操作一个node->next链表(包括head),也就是说,遍历一下这个链表就可以了,那么怎样遍历呢?用一个指针指向链表的头,然后遍历。在这里就表现为一个二级指针。

这段代码实践上的意义比理论上的意义要真切得多,所以,还是多看源代码吧。在内核里面,这种代码比比皆是。

 posted on 2013-02-12 13:10  万事屋madao  阅读(285)  评论(0编辑  收藏  举报