Pointer === --- ###### tags: `C` 找到一段創世神 Linus Torvalds 對於 pointer 發表的言論,覺得蠻有趣的紀錄一下 https://meta.slashdot.org/story/12/10/11/0030249/linus-torvalds-answers-your-questions 你如果覺得你很會用 Pointer 的話,可以看看這篇,驗證一下你的答案。 --- > At the opposite end of the spectrum, I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I've seen too many people who delete a singly-linked list entry by keeping track of the "prev" entry, and then to delete the entry, doing something like > > if (prev) prev->next = entry->next; else list_head = entry->next; > > and whenever I see code like that, I just go "This person doesn't understand pointers". And it's sadly quite common. > > People who understand pointers just use a "pointer to the entry pointer", and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a "*pp = entry->next". Google 了一下,找到一個解釋得很好的文章,以下摘錄 code https://grisha.org/blog/2013/04/02/linus-on-understanding-pointers/ 假設有一個 singly-linked list ```c= typedef struct list_entry { int val; struct list_entry *next; } list_entry; ``` 如果要砍掉 val == to_remove 的所有 entries,有兩種寫法,哪個比較好,看 code 就知道 ```c= list_entry *entry = head; /* assuming head exists and is the first entry of the list */ list_entry *prev = NULL; while (entry) { if (entry->val == to_remove) /* this is the one to remove */ if (prev) prev->next = entry->next; /* remove the entry */ else head = entry->next; /* special case - first entry */ /* move on to the next entry */ prev = entry; entry = entry->next; } ``` ```c= list_entry **pp = &head; /* pointer to a pointer */ list_entry *entry = head; while (entry) { if (entry->val == to_remove) *pp = entry->next; pp = &entry->next; entry = entry->next; } ``` 不過看到了 kernel 中 `find_vma_links` 的寫法後,又學到了可以再簡寫成 ```c= list_entry **pp = &head; while (*pp) { if ((*pp)->val == to_remove) *pp = (*pp)->next; pp = &entry->next; } ```