zoukankan      html  css  js  c++  java
  • 对话 Linus Torvalds:大多数黑客甚至连指针都未理解

    对话Linus Torvalds:大多数黑客甚至连指针都未理解
     

    几周前, Linus Torvalds在Slashdot上回答了一些问题。其中有一条引发了开发者们的强烈关注,当被问到他心目中的内核黑客时,他说自己这些日子已经不怎么看代码了,除非是帮别人审查。他稍微暂停了一下,坦言那些“狡猾”的通过文件名查找高速缓存又抱怨自己能力一般的内核“恶魔”(黑客)才是他欣赏的。

    他说:

    相反,很多人连低水平的内核编程都还没学好。像lockless用名字查找(name lookup)功能即使不大也不复杂,却是指针到指针的一个简单及良好的使用方法。比如,我曾看见过许多人通过跟踪上一页条目删除一个单向链接的列表项,然后删除该条目。例如:

    1. if (prev)  
    2.     prev->next = entry->next;  
    3. else  
    4.     list_head = entry->next; 

    每当我看到这些的代码,我会说:“此人不了解指针”。这还是一个可悲的、常见的问题。

    如果开发者能够理解指针,只需要使用“指向该条目的指针”并初始化list_head,然后贯穿列表,此时无需使用任何条件语句即可删除该条目,只需通过 *pp = entry->next。

    我想我理解指针,但不幸的是,如果要实现删除函数,我会一直保持跟踪前面的列表节点。这里是代码草稿:

    不理解指针的人做法:

    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 * next = curr->next;  
    17.         if (rm(curr))  
    18.         {  
    19.             if (prev)  
    20.                 prev->next = curr->next;  
    21.             else  
    22.                 head = curr->next;  
    23.             free(curr);  
    24.         }  
    25.         else  
    26.             prev = curr;  
    27.         curr = next;  
    28.     }  
    29.     return head;  

    这个链表很简单,但可以把每个节点的指针和sentinel值构建成了一个完美的结构体,但是修改这个表的代码需要很精妙。难怪链表功能会常出现在许多面试环节中。

    上面执行的代码是处理从列表头中删除任何节点所需的条件。

    现在,让我们好好记住Linus Torvalds执行代码。在这种情况下,我们通过一个指针指向列表头来贯穿列表遍历修改。

    Two star programming:

    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.     }  

    好多了!最关键的部分在于:链表中的链接都是指针,因此指针到指针是修改链表的首选方案。

    改进版的remove_if()是一个使用双重星号的例子,双重星号象征着两重间接寻址,再加一个星(third star)又会太过多余。


  • 相关阅读:
    Direct hosting of SMB over TCP/IP
    学习 Linux,302(混合环境): 概念
    脚本
    linux加入windows域
    Internet传输协议-TCP
    vCenter Single Sign On 5.1 best practices
    Zoning and LUN Masking
    Fiber Channel SAN Storage
    How to check WWN and Multipathing on Windows Server
    在Windows中监视IO性能
  • 原文地址:https://www.cnblogs.com/leonxyzh/p/7289128.html
Copyright © 2011-2022 走看看