我正在学习C语言,到目前为止对语言有了不错的理解,我最近实现了一个非常简单的单链表。我曾与Linus Torvalds一起观看过Ted演讲,他提到了良好的代码与糟糕的代码,并提供了从链表中删除条目的两个例子:
/*bad code*/
remove_list_entry(entry){
prev = NULL;
walk = head;
while(walk != entry){
prev = walk;
walk = walk->next;
}
if(!prev)
head = entry->next;
else
prev->next = entry->next;
/*good code*/
remove_list_entry(entry){
indirect = &head;
while ((*indirect) != entry)
indirect = &(*indirect)->next;
*indirect = entry->next;
}
在我看来,他的良好代码示例很有效,但我自己也不会想到这一点。在使用C编程时,我可以遵循哪些良好实践建议?或者像他在他的例子中那样操纵指针的某些方法?以及在C语言编程时要避免的不良习惯和做法。我希望这不是一个太宽泛的问题。
答案 0 :(得分:6)
这是我的简短回答:你没错,但Linus也不是。我是一名经验丰富的程序员,在C语言方面有很多工作,我发现他的链接列表代码版本基本上不可读。我自己永远不会写这段代码。
他使用这个例子并不是为了表明好与不好,而是为了证明对问题的更清晰思考可以导致更紧凑的解决方案并且具有更少的边缘情况(和条件流)来考虑和测试。在那个分数上,他是一个进步。
“可读性”通常被认为是现代编程中的第一顺序考虑因素,因此您和其他人都可以快速理解代码试图实现的目标。这是针对复杂性和性能考虑因素进行的,但需要权衡利弊。
答案 1 :(得分:3)
Linus的特定示例演示了如何通过使用间接来避免分支。由head = entry->next
和prev->next = entry->next
表示的两个单独的代码路径可以通过使用指向分配给*indirect = entry->next
的事物的指针合并为一个。
这种方法可以产生非常优雅的线性代码,分支更少。
一般模式是你可以改变这段代码:
int a = 0, b = 0;
if (some_condition) {
a = 1;
} else if (other_condition) {
b = 1;
}
/* continue working with "a" and "b" */
分为:
int a = 0, b = 0;
int *p;
if (some_condition) {
p = &a;
} else if (other_condition) {
p = &b;
} else {
p = NULL;
}
/* consequently, work only with "*p" and never again touch "a" or "b" */
if (p) {
*p = 1;
}