代码阅读有自身的一套技能,重要的是能够确定什么时候使用哪项技术。本书中,作者使用600多个现实的例子,向读者展示如何区分好的(和坏的)代码,如何阅读,应该注意什么,以及如何使用这些知识改进自己的代码。养成阅读高品质代码的习惯,可以提高编写代码的能力。
\r\n 阅读代码是程序员的基本技能,同时也是软件开发、维护、演进、审查和重用过程中不可或缺的组成部分。本书首次将阅读代码作为一项独立课题,系统性地加以论述。本书引用的代码均取材于开放源码项目——所有程序员都应该珍视的宝库。本书围绕代码阅读,详细论述了相关的知识与技能。“他山之石、可以攻玉”,通过仔细阅读并学习本书,可以快速地提高读者代码阅读的技能与技巧,进而从现有的优秀代码、算法、构架、设计中汲取营养,提高自身的开发与设计能力。
\r\n 本书适用于对程序设计的基本知识有一定了解,并想进一步提高自身开发能力的读者。
第1章 导论\r\n 1.1 为什么以及如何阅读代码\r\n 1.2 如何阅读本书\r\n 进阶读物\r\n第2章 基本编程元素\r\n 2.1 一个完整的程序\r\n 2.2 函数和全局变量\r\n 2.3 while循环、条件和块\r\n 2.4 switch语句\r\n 2.5 for循环\r\n 2.6 break和continue语句\r\n 2.7 字符和布尔型表达式\r\n 2.8 goto语句\r\n 2.9 小范围重构\r\n 2.10 do循环和整型表达式\r\n 2.11 再论控制结构\r\n 进阶读物\r\n第3章 高级C数据类型\r\n 3.1 指针\r\n 3.2 结构\r\n 3.3 共用体\r\n 3.4 动态内存分配\r\n 3.5 typedef声明\r\n 进阶读物\r\n第4章 C数据结构\r\n 4.1 向量\r\n 4.2 矩阵和表\r\n 4.3 栈\r\n 4.4 队列\r\n 4.5 映射\r\n 4.6 集合\r\n 4.7 链表\r\n 4.8 树\r\n 4.9 图\r\n 进阶读物 \r\n第5章 高级控制流程\r\n 5.1 递归\r\n 5.2 异常\r\n 5.3 并行处理\r\n 5.4 信号\r\n 5.5 非局部跳转\r\n 5.6 宏替换\r\n 进阶读物\r\n第6章 应对大型项目\r\n 6.1 设计与实现技术\r\n 6.2 项目的组织\r\n 6.3 编译过程和制作文件\r\n 6.4 配置\r\n 6.5 修订控制\r\n 6.6 项目的专有工具\r\n 6.7 测试\r\n 进阶读物\r\n第7章 编码规范和约定\r\n 7.1 文件的命名及组织\r\n 7.2 缩进\r\n 7.3 编排\r\n 7.4 命名约定\r\n 7.5 编程实践\r\n 7.6 过程规范\r\n 进阶读物 \r\n第8章 文档\r\n 8.1 文档的类型\r\n 8.2 阅读文档\r\n 8.3 文档存在的问题\r\n 8.4 其他文档来源\r\n 8.5 常见的开放源码文档格式\r\n 进阶读物\r\n第9章 系统构架\r\n 9.1 系统的结构\r\n 9.2 控制模型\r\n 9.3 元素封装\r\n 9.4 构架重用\r\n 进阶读物 \r\n第10章 代码阅读工具\r\n 10.1 正规表达式\r\n 10.2 用编辑器浏览代码\r\n 10.3 用grep搜索代码\r\n 10.4 找出文件的差异\r\n 10.5 开发自己的工具\r\n 10.6 用编译器来协助代码阅读\r\n 10.7 代码浏览器和美化器\r\n 10.8 运行期间的工具\r\n 10.9 非软件工具\r\n 可用工具和进阶读物\r\n第11章 一个完整的例子\r\n 11.1 概况\r\n 11.2 攻坚计划\r\n 11.3 代码重用\r\n 11.4 测试与调试\r\n 11.5 文档\r\n 11.6 观察报告\r\n附录A 代码概况\r\n附录B 阅读代码的格言
有一扇窗,从未打开,却要永远关闭
有一些人,确实存在,我们却无缘相见
有一种生活,还没有到来,我们却已永远离开
开放源码——程序员的天堂
好的程序就如同好的音乐一样,它们完成得那么巧妙,那么完美,体现出完全没有词藻的美丽。就如同好的音乐能够改变你对人生的看法、让你重新审视你的生活、和多年前的人进行跨时空的交流一样,作为软件开发人员,好的程序所能够带来的感受丝毫不逊于音乐给你带来的冲击。更为难得的是,这些宝贵的程序往往并非由“权威人士”、“享誉海内外的专家”所编写,它们是由一个个普通的程序员写就。这些程序员和读者没有什么不同。虽然这些程序员并非吒咤风云的人物,但专业创造了专家,长时间集中在某个领域中就能够创建出所有程序员都应该珍视的财富。就如同古代的米开朗基罗,相比于当时那些声名显赫的主教、贵族来说,他是多么的微不足道,但时至今日,那些人和他们的名字都随风漂逝,昔日的荣光都随时间而暗淡,而米开朗基罗的名字却铭刻在大多数甚至是普通人的心中,许多人的脑海中都能回忆出那些完美的雕塑——《大卫》、《创世纪》。这份荣耀在文艺史上可能无人能及。
但一个不可忽视的现实是,对于大部分正在使用的软件,我们很难看到它们的源代码,从而也就失去了欣赏和从中学习的机会。和音乐不同的是,你不可能花钱买到一份拷贝回家欣赏。幸运的是,现在情况已经发生了很大的改变,我们拥有了一个宝贵的资源——开放源码项目。
开放源码和商业产品的源代码有着本质上的不同。这种不同体现在以下几个方面:
1. 开放源码项目中的大部分代码都经历过许多人的阅读和检查,在商业产品中由于人力和版权方面的限制,根本不可能做到这一点。同时,由于作者在开发时就意识到自己编写的代码要被别人阅读,故而无论是在规范的遵守、算法的优化方面都会格外用心。
2. 开放源码由于没有严格的时间限制,少了时间与质量的权衡,从而产生的代码质量更高,对于读者也更有借鉴作用。例如,面向普通用户的软件,比如游戏、娱乐软件等,大都会选择在圣诞节和暑假之前发布,而为了满足市场销售的需要,软件新版本的开发工作也大都定在圣诞节和暑假之前二到三个月必须完成。这就要求软件的开发人员必须严格遵守时间上的要求。
3. 开放源码能够优胜劣汰,拥有更快的更新速度。开放源码项目一般接受各种形式的反馈。来自全世界的代码阅读者都可以及时地反馈自己发现的问题,或好的看法。在这里,评判优劣的惟一标准是代码的质量。好的代码经历住时间的考验,留存下来。不好的代码和不太合格的代码提交者随着时间的推移迅速地淘汰。而在商业产品的源代码中,一些遗留代码中存在的问题可能永远得不到改正,因为开发它的人员已经离开公司或者从事其他工作,只要这段代码能够工作,没有人再去关注它的优劣。
4. 开放源码没有权威崇拜。
开放源码的世界里没有阿谀奉承、阴奉阳违、沽名钓誉、挂着羊头卖狗肉、恬不知耻,所有的程序都经过无数人的检验。正是由于开放源码具有这些特性,使得它成为程序员学习和提高的首选材料。
代码阅读——入门与提高的必由之路
信息时代,我们整个社会的知识更新速度越来越快,而位于信息时代风口浪尖上的计算机技术,更是日新月益。作为程序员,总是要不断地学习新的知识。但我们要保持清醒,如何体现出我们的价值呢?难道是我们掌握了多少知识吗?不对!我们的价值归根到底要体现在我们创造出的系统上。否则空有满腹经伦,到头来也不过是纸上谈兵,于国于人毫无益处。
计算机科学是一门实践性很强的科学,许多内容往往在书本上根本学不到。就拿项目的组织来说,没有什么书籍专门论述应该如何组织与管理项目的目录结构,因为这本身就是一种见仁见智的活动,要受到各种因素的影响。代码中往往凝聚着许多实践性的知识,通过阅读代码才能真正掌握软件开发的真谛。我们可以将“书籍是人类进步的阶梯”,扩展成“一切承载人类知识的材料,都是人类进步的阶梯”。
代码阅读是一件如此基本的事情,以至于人们根本没有意识到它的存在。这本书第一次将代码阅读这一主题单独列出来加以探讨,可以说极具开创性。
代码阅读不是一件容易的工作,但却是一件不得不做的工作,无论是工作的移交、新手的入门、或是加入新的项目,都要阅读大量由他人编写的代码。我们可能不止一次地听到过他人抱怨:与其读他人的代码,还不如自己去写更为轻松。可见,代码阅读任务可能远比实现一个链表或树形数据结构要复杂困难。但代码阅读也并非完全无章可循。掌握了一些常见的技巧以及常用的工具之后,能够有效地降低代码阅读的难度,提高工作效率。
我曾向一位资深的开发人员询问过,应该如何提高自身的开发与设计能力。他的回答是,广泛地阅读一些现有的构架,比如Apple的开发框架、Borland的OWL和Delphi、Smalltalk、MFC等,了解它们是如何组织的。计算机科学就是这样一门学科,入门十分容易,不需要深奥的数学知识,也没有复杂的物理模型;但要想提高却很难,真正能够叱诧风云、引领潮流的人却少之又少。这就有如人生,在蹒跚学步之时,主要的精力都要放在看脚下的路面上,注意路上的坎坷和荆棘;随着年龄的增长,当走路越来越稳健时,却迷失了方向,不知道应该走向何方。这个时候脚下的路已经不再重要,你需要从先哲们留下的只字片言,别人走过的“路”中汲取灵感,确定自己的方向。
由于微软Windows的广泛采用,使得许多程序员只将注意力放在Windows平台上,这种做法有失偏颇。做为文秘人员,当然可以这样做,因为微软在桌面系统上的确十分成功,基本覆盖了文秘人员对计算机的所有需求。但做为开发人员,必须跳出Windows这口“井”。总是局限在Windows这口“井”中,可能会限制您的思路与视野。当设计与实现复杂的系统时,需要借鉴许多前人的经验,而这时候,您就需要开阔的视野,才能从更为广泛的空间中吸收所需要的知识。跳出Windows之后,您能看到各种各样的构架,各种各样的抽象方法,各种各样不同的系统设计,也许其中一种就很适合您使用,不再需要冥思苦想,绞尽脑汁,不再进行大量的尝试,不再受大量的挫折之苦。Microsoft是一家出色的公司,为用户提供了很有用的产品,但Microsoft并非软件的全部。有许许多多出色的操作系统、编辑工具、各色软件需要我们去认识和借鉴,甚至包括那些已经逐渐淡出人们记忆的软件。因为我们不是软件的用户,我们是软件的开发者,我们需要借鉴前代的经验,才能更好地前进。那些消逝的软件并非由于它们不优秀,只不过它们不适合于生存下来而已。存活下来的软件也并不一定是优秀的软件,只不过它们适合于生存下来而已。就好像许多古代文明,我们现在只能通过一些石块来追溯它们昔日的辉煌,有记录的内容都已经随着时间的流逝而消失,尽管它们比石块更能清楚地告诉我们想要知道的内容,尽管石块根本就是这些文明中最无关紧要的部分。
在夕阳西下的时间,泡上一杯茶,合上笔记本,揉一下看了一会源代码有些累的眼睛,伸个懒腰。这是不是有一些“采菊东篱下,悠然见南山”的意境呢?只不过陶渊明种的是菊花,我们播种与收获的是代码而已。
阅读建议——以本书为主线
这是一本外延性极广的书籍,只需要看看本书每章列出的进阶读物,以及附在书后的200多项参考书目就能够认识到这一点。在阅读时,要将本书作为掌握代码阅读的相关知识,提高自身设计与开发能力的大纲。在一本书中详尽地介绍代码阅读过程中涉及的所有知识是不可能的,这就决定本书必然会对相关内容做出取舍,有些部分详加叙述(和一些书籍相比,即使是详加叙述的内容也要简短的多),有些部分只能粗略带过。如果在阅读过程中对本书提及的内容不甚了了,则要停下来,查找相应的参考书,掌握相关的内容。
所以,在阅读本书的过程中,最好以本书为主线,不时地查阅相关的参考资料,分析研读本书引用的源代码,然后回到本书继续后面的内容。这样,才能在掌握本书精髓的基础上真正有所提高。
本书的另一大特色是所引用的每段代码,哪怕只有一行,也都摘自真正的开放源码项目。首先,这使得本书所讲述的内容都言之确凿,其次,也使得读者在阅读本书的过程中逐渐熟悉了许多开放源码项目,对它们有了大致的了解。由于所有的代码都有真实的上下文,读者可以切实感受到本书讲授的内容,同时,还可以适度扩大阅读的量。
所以,在阅读本书的过程中,不要急于读完,而是要不断停下来,将其中的每部分内容都加以参详,才不至于“入宝山而空回”。
致谢
作为一名程序员,我首先得感谢清华大学出版社能够及时引进这部图书。使我们能以更便宜的价格(相对于英文原版)、更通畅的渠道和更高的质量得到这样一本影响深远的优秀书籍。
感谢在我成长与工作过程中一直帮助我的家人、同学和朋友。