![C语言最佳实践](https://wfqqreader-1252317822.image.myqcloud.com/cover/885/53286885/b_53286885.jpg)
1.2.2 妙手理码
拿到坏代码时,一个很好的习惯就是对代码按照编码规范的要求进行整理。这一过程本身就是阅读代码的过程,通过整理,我们可以使代码变得更加清晰易懂,也可能发现并解决一些潜在的问题。
程序清单1.2是按照符合惯例的编码风格对程序清单1.1中的代码进行修改后的版本。
程序清单1.2 一个简单的链表实现(整理后)
#include <stdio.h> #include <stdlib.h> struct linked_list { const char *title; struct linked_list *next; } /* Creates and initializes a new linked list. */ static struct linked_list *init_linked_list(void); /* Dumps the contents of a linked list */ static void dump_linked_list(struct linked_list *list); /* Destroys a linked list */ static void destroy_linked_list(struct linked_list *list); static const char *titles[] = { "第1章 提高代码可读性", "第2章 用好写好头文件", "第3章 消除编译警告", "第4章 常量的定义和使用", "第5章 充分利用构建系统生成器" }; int main(void) { /* Creates and initialize a new linked list with chapter titles */ struct linked_list *list = init_linked_list(); printf("A new linked list has been created and initialized: \n"); dump_linked_list(list); // dump the contents destory_linked_list(list); // destroy the list return 0; } struct linked_list *init_linked_list(void) { struct linked_list *head = NULL; /* allocates a node for the head of the linked list */ struct linked_list *head = (struct linked_list*)malloc(sizeof(*head)); /* initializes the head node */ head->title = titles[0]; head->next = NULL; struct linked_list *p = head; for (int i = 1; i < 5; i++) { struct linked_list *a; a = (struct linked_list*)malloc(sizeof(*a)); a->title = titles[i]; a->next = NULL; p->next = a; p = a; } return head; }
可以看到,修改之后的代码排版错落有致,逻辑清晰,给人一种赏心悦目的感觉。除了排版,我们还在如下6个方面对原有的代码做了调整,以便提高代码可读性以及代码质量。
● 将struct linked_list
结构体中的第一个成员(elem
)更名为更具实际意义的title
。
● 将init_linked_list()
函数声明为static
类型,避免命名污染。
● 将display()
函数重命名为dump_linked_list()
,并声明为static
类型。display
这个术语通常用于在窗口或者页面中显示一个图形,而在本例中,展示一个链表通常意味着将其内容转储(dump)到指定的文件或者标准输出(标准输出本质上也是文件),以便事后查看或者调试。因此,使用dump
这个术语来命名这个函数,显然要比使用display
强很多。
● 新增destroy_linked_list()
函数,用于销毁新创建的链表,并声明为static
类型。原有代码在main()
函数返回时并未做内存的清理工作。尽管在这个简单的链表实现中不必如此严谨,但作为专业程序员,我们应该养成良好的习惯并逐渐形成条件反射:既然有链表的创建函数,就应该有对应的链表销毁函数。
● 在init_linked_list()
函数的实现中,移除了不必要且易混淆的temp
变量。
● 使用sizeof(*head)
的写法替代了sizeof(struct linked_list)
的写法,避免代码行过长。
注意,上述代码中未包含dump_linked_list()
和destroy_linked_list()
两个函数的实现,有兴趣的读者可自行实现。