---
# System prepended metadata

title: Pointer
tags: [C]

---

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;
}
```