声明:关于代码阅读的研究,很多思想和文字是来自《代码阅读》这本书,再加上自己的学习和工作经验。可以说是类似读书笔记的,我把它作为了毕业论文的第8章,并结合了自己的毕设作品进行解释,毕设源代码github下载地址:https://github.com/chinaran/A-LL1-Compiler

8.6 代码阅读工具和技巧

在阅读代码时,大部分时间你会很幸运能够访问所阅读的代码。这意味着可以使用工具来处理源代码,以提高阅读效率和帮助理解。

8.6.1 使用正则表达式查找。

许多词法工具的强大和灵活都来自正则表达式的使用。正则表达式可看做一个匹配字符串的配方,由字符序列组成。大多数字符只匹配其自身,而元字符则具有特殊意义。通过使用常规字符和元字符的组合创建正则表达式,指定一个能够匹配你想要查找的确切代码项的配方。常用的正则表达式元字符如表8-1所示。

常用正则表达式元字符   表 8-1 常用正则表达式元字符

大多数编程风格指南都规定,编写函数定义时,函数名要另起一行(尤其是C++/C,Java并没有此规定)。因此,通过使用 ^function name 这样的正则表达式查找,就可以找到函数的定义,如下图所示。关于正则表达式更多详细的介绍,可以参考任何一本你能找到的编程书籍以及专门介绍正则表达式的专业书籍。 这样的使用正则表达式进行查找,可以精确地定位到想要查看的位置。

Sublime Text 2 中通过^function name 方式查找函数定义   图 8-12 Sublime Text 2 中通过 ^function name 方式查找函数定义

另外一个常用的高级查找方法是全文件搜索,尤其是项目较大时,有些代码记得不清楚,想去查看详细的用法,只需记住几个字母,就能搜索出来;还有阅读代码时,当有不懂的常量或函数,或者看看它们在整个项目中的使用情况,都使用全文件搜索。下图为在 Visual Studio 2010 中搜索整个项目中常量 EQUAL 的定义和使用情况。

全文件搜索示例   图 8-13 全文件搜索示例

8.6.2 找出文件差异。

重用代码的一个诱人的简便方法是创建相应源代码的副本,根据需要进行修改。这种代码重用方式有个问题,就是创建了代码库的两种分支版本,最终导致同一源代码文件有两份存在差异的版本。这样,就必须比较它们之间的不同,然后修改使其保持一致。

另一种需要比较文件差异的情况是,在一个团队并行开发一个项目时(假设已使用版本控制系统),有可能多人同时改了同样的代码位置,这样提交自己的版本就不会成功,需要使用 Diff 功能查看代码冲突的地方。即使是平时提交代码,一个好的习惯是先使用 Diff,查看和之前的版本之间的差别,确认自己修改的地方,防止误操作。

TortoiseSvn Diff 示例   图 8-14 TortoiseSvn Diff 示例(来自谷歌图片搜索)

上图中,红色区域代表冲突,需要解决;黄色区域代表新增,橙色区域代表删除。除了冲突需要手动解决,其他的 TortoiseSvn 可以智能的合并。

8.6.3 借助编译器阅读代码。

编译器是对代码进行精确分析的工具。编译器不仅能够完成源代码到目标代码的转换,还可用于在各种不同的细节层面分析程序。下列方式可通过编译器挖掘有关程序的信息。

● 生成的警告信息。

● 找出生成错误消息的代码。

● 生成程序清单。

● 获取预处理器的清单

● 分析生成的符号(汇编)代码。

● 完成最终目标代码。

这些方法并不完全适用于所有的编译器和语言,但其中的一些有助于更好地了解当前所处理的代码。

8.6.4 非软件工具。

把你觉得难于理解的代码打印到纸上,常见的计算机屏幕由大约100万个点构成;激光打印机打出的一页纸包含至少3000万个点。这种不同的结果使一页纸上包含更多信息,并且眼睛相对不易疲劳。更重要的是,可以把打印出来的资料带到任何可令自己更加专注的地方去,并且可以高亮代码、划线,以及在空白处做注释,也可以使用荧光笔、彩色笔、便利贴,以及其他任何工具来帮助理解代码。

也可以通过像其他人解释某个代码片段来获得更好的理解。向其他人表述程序的运行这种行为可以将自己的思维调整到另一种步调,发现某些忽略的细节。


最后,为了理解复杂的算法或者微妙的数据结构,请选择一个安静的环境,全力以赴,不要借助计算机化或自动化的帮助。在非常专心时,打断容易使人分心。心理学家使用术语“流”来解释对一项任务接近于冥想的投入,一种与内心中欣喜状态联系而忘记时间的情况(关于“心流”可以参看《暗时间》和《番茄工作法图解》)。这正是那种你在分析复杂代码时希望能进入的状态。因此,要建立一个在需要时能够在学习和工作中不受打扰的环境和习惯。