最近偶尔看到一篇关于Linus Torvalds的访问,大神说大部分人都不理解指针。假设被要求写一段链表删除节点的程序,大多数的做法都是跟踪两个指针,当前指针cur和其父节点pre,这种实现很容易理解,但是并没有用到指针的精髓。
Linus是怎么写的呢,且看源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 |
//链表之two star programming #include <stdio.h> typedef
struct node { int
value; struct
node *next; }listNode; listNode *insert(listNode *head, int
value) { listNode *newNode = new
listNode; newNode->value = value; newNode->next = head; return
newNode; } void
erase(listNode **head_in, int
value) { listNode **cur = head_in; while
(*cur) { listNode *p = *cur; if
(p->value == value) { *cur = p->next; delete
p; } else { cur = &(p->next); } } //return head; } void
printList(listNode *head) { listNode *p = head; while (p) { printf ( "%d " , p->value); p = p->next; } printf ( "\n" ); } int
main() { listNode *head = NULL; int
select, a; do { printf ( "请输入选择 1--插入, 2--删除, 3--输出,其他跳出\n" ); scanf ( "%d" , &select); if (select == 1) { printf ( "输入将要插入的值, -1表示结束\n" ); while ( scanf ( "%d" , &a), a != -1) { head = insert(head, a); } } else
if (select == 2) { printf ( "输入将要删除的值, -1表示结束\n" ); while ( scanf ( "%d" , &a), a != -1) { erase(&head, a); } } else
if (select == 3) { printList(head); } else
break ; } while
(1); getchar (); return
0; } |
运行结果
在链表的删除节点函数earse()中,并不是把头结点指针head作为参数传入,而是传入指针head的引用,小雨来分析一下运行过程,直接上图说明
可以看出cur的移动比较有意思,它是沿着节点之间的指针移动的,在这里,我们也可以把指针当成一种特殊的节点。
当然现在并不提倡这种编程风格,虽然看起来很简洁,但是太晦涩,不能让人一眼看懂,Linus说一般操作系统核心部分用这种方式。
删除链表之two star programming,布布扣,bubuko.com
原文:http://www.cnblogs.com/rain-lei/p/3590561.html