如何了解别人的代码_第1页
如何了解别人的代码_第2页
如何了解别人的代码_第3页
如何了解别人的代码_第4页
如何了解别人的代码_第5页
已阅读5页,还剩2页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、转如何看懂别人的代码张惠寿2011年07月26日星期二16:26|131次浏览|0条评论今天还是研究生一年级生活的最后一个学期了。年前去了北京导师那里,自己的差距很大。老师留了作业,让我把老师讲过的代码,重新注释起来,可是我是初级选手,连代码都看不清楚呢。于是今天上网找来相关文章,阅读下。了解下。加油啦。如何阅读源代码时间:2010-03-04/分类:C/C+语言/您是第661位浏览者/0个评论发表评论+第一章:导论+1 .要养成一个习惯,经常花时间阅读别人编写的高品质代码.2 .要有选择地阅读代码,同时,还要有自己的目标.您是想学习新的模式|编码风格|还是满足某些需求的方法.3 .要注意并重

2、视代码中特殊的非功能性需求,这些需求也许会导致特殊的实现风格.4 .在现有的代码上工作时,请与作者和维护人员进行必要的协调,以避免重复劳动或产生厌恶情绪.5 .请将从开放源码软件中得到的益处看作是一项贷款,尽可能地寻找各种方式来回报开放源码社团.6 .多数情况下,如果您想要了解别人会如何完成这个功能呢?”,除了阅读代码以外,没有更好的方法.7 .在寻找bug时,请从问题的表现形式到问题的根源来分析代码.不要沿着不相关的路径(误入歧途).8 .我们要充分利用调试器|编译器给出的警告或输出的符号代码|系统调用跟踪器|数据库结构化查询语言的日志机制|包转储工具和Windows的消息侦查程序,定出的b

3、ug的位置.9 .对于那些大型且组织良好的系统,您只需要最低限度地了解它的全部功能,就能够对它做出修改.10 .当向系统中增加新功能时,首先的任务就是找到实现类似特性的代码,将它作为待实现功能的模板.11 .从特性的功能描述到代码的实现,可以按照字符串消息,或使用关键词来搜索代码.12 .在移植代码或彳改接口时,您可以通过编译器直接定位出问题涉及的范围,从而减少代码阅读的工作量.13 .进行重构时,您从一个能够正常工作的系统开始做起,希望确保结束时系统能够正常工作.一套恰当的测试用例(testcase)可以帮助您满足此项约束.14 .阅读代码寻找重构机会时,先从系统的构架开始,然后逐步细化,能

4、够获得最大的效益.15 .代码的可重用性是一个很诱人,但难以理解与分离,可以试着寻找粒度更大一些的包,甚至其他代码.16 .在复查软彳系统时,要注意,系统是由很多部分组成的,不仅仅只是执行语句.还要注意分析以下内容:文件和目录结构|生成和配置过程|用户界面和系统的文档.18 .可以将软件复查作为一个学习|讲授|援之以手和接受帮助的机会.+第二章:基本编程元素+19 .第一次分析一个程序时,main是一个好的起始点.20 .层叠if-elseif-else序列可以看作是由互斥选择项组成的选择结构21 .有时,要想了解程序在某一方面的功能,运行它可能比阅读源代码更为恰当.22 .在分析重要的程序时

5、,最好首先识别出重要的组成部分.23 .了解局部的命名约定,利用它们来猜测变量和函数的功能用途.24 .当基于猜测修改代码时,您应该设计能够验证最初假设的过程.这个过程可能包括用编译器进行检查|引入断言|或者执行适当的测试用例.25 .理解了代码的某一部分,可能帮助你理解余下的代码.26 .解决困难的代码要从容易的部分入手.27 .要养成遇到库元素就去阅读相关文档的习惯;这将会增强您阅读和编写代码的能力.28 .代码阅读有许多可选择的策略:自底向上和自顶向下的分析|应用试探法和检查注释和外部文档,应该依据问题的需要尝试所有这些方法.29 .for(i=0;i30 .涉及两项不等测试(其中一项包

6、括相等条件)的比较表达式可以看作是区间成员测试.31 .我们经常可以将表达式应用在样本数据上,借以了解它的含义.32 .使用DeMorgan法则简化复杂的逻辑表达式.33 .在阅读逻辑乘表达式时,问题可以认为正在分析的表达式以左的表达式均为true;在阅读逻辑和表达式时,类似地,可以认为正在分析的表达式以左的表达式均为false.34 .重新组织您控制的代码,使之更为易读.35 .将使用条件运行符?:的表达式理解为if代码.36 .不需要为了效率,牺牲代码白易读性.37 .高效的算法和特殊的优化确实有可能使得代码更为复杂,从而更难理解,但这并不意味着使代码更为紧凑和不易读会提高它的效率.38

7、.创造性的代码布局可以用来提高代码的易读性39 .我们可以使用空格|临时变量和括号提高表达式的易读性.40 .在阅读您所控制的代码时,要养成添加注释的习惯.41 .我们可以用好的缩进以及对变量名称的明智选择,提高编写欠佳的程序的易读性.42 .用diff程序分析程序的修订历史时,如果这段历史跨越了整体重新缩排,常常可以通过指定-w选项,让diff忽略空白差异,避免由于更改了缩进层次而引入的噪音.43 .do循环的循环体至少执行一次.44 .执行算术运算时,当b=2n-1时,可以将a&b理解为a%(b+1).45 .将an理解为a/k,k=2n.47 .每次只分析一个控制结构,将它的内容看作是一

8、个黑盒.48 .将每个控制结构的控制表达式看作是它所包含代码的断言49 .return,goto,break和continue语句,还有异常,都会影响结构化的执行流程.由于这些语句一般都会终止或重新开始正在进行的循环,因此要单独推理它们的行为.50 .用复杂循环的变式和不变式,对循环进行推理.51 .使用保持含义不变的变换重新安排代码,简化代码的推理工作.+第三章:高级C数据类型+52 .了解特定语言构造所服务的功能之后,就能够更好地理解使用它们的代码.53 .识别并归类使用指针的理由.54 .在C程序中,指针一般用来构造链式数据结构|动态分配的数据结构|实现引用调用|访问和迭代数据元素|传递

9、数组参数|引用函数|作为其他值的另名|代表字符串|以及直接访问系统内存.55 .以引用传递的参数可以用来返回函数的结果,或者避免参数复制带来的开销.56 .指向数组元素地址的指针,可以访问位于特定索引位置的元素.57 .指向数组元素的指针和相应的数组索引,作用在二者上的运算具有相同的语义.58 .使用全局或static局部变量的函数大多数情况都不可重入(reentrant).59 .字符指针不同于字符数组.60 .识别和归类应用结构或共用体的每种理由.61 .C语言中的结构将多个数据元素集合在一起,使得它们可以作为一个整体来使用,用来从函数中返回多个数据元素|构造链式数据结构|映射数据在硬件设

10、备|网络链接和存储介质上的组织方式|实现抽象数据类型|以及以面向对象的方式编程.62 .共用体在C程序中主要用于优化存储空间的利用|实现多态|以及访问数据不同的内部表达方式.63 .一个指针,在初始化为指向N个元素的存储空间之后,就可以作为N个元素的数组来使用.64 .动态分配的内在块可以电焊工地释放,或在程序结束时释放,或由垃圾回收器来完成回收;在栈上分配的内存块当分配它的函数退出后释放65 .C程序使用typedef声明促进抽象,并增强代码的易读性,从而防范可移植性问题,并模拟C+和Java的类声明行为.66 .可以将typedef声明理解成变量定义:变量的名称就是类型的名称;变量的类型就

11、是与该名称对应的类型.+第四章:C数据结构+67 .根据底层的抽象数据类型理解显式的数据结构操作68 .C语言中,一般使用内建的数组类型实现向量,不再对底层实现进行抽象.69 .N个元素的数组可以被序列for(i=0;i70 .表达式sizeof(x)总会得到用memset或memcpy处理数组x(不是指针)所需的正确字节数.71 .区间一般用区间内的第一个元素和区间后的第一个元素来表示72 .不对称区间中元素的数目等于高位边界与低位边界的差73 .当不对称区间的高位边界等于低位边界时,区间为空.74 .不对称区间中的低位边界代表区间的第一个元素;高位边界代表区间外的第一个元素.75 .结构的

12、数组常常表示由记录和字段组成的表.76 .指向结构的指针常常表示访问底层记录和字段的游标77 .动态分配的矩阵一般存储为指向数组列的指针或指向元素指针的指针;这两种类型都可以按照二维数组进行访问.78 .以数组形式存储的动态分配矩阵,用自定义访问函数定位它们的元素.79 .抽象数据类型为底层实现元素的使用(或误用)方式提供一种信心的量度.80 .数组用从0开始的顺序整数为键,组织查找表.81 .数组经常用来对控制Z构进行高效编码,简化程序的逻辑.82 .通过在数组中每个位置存储一个数据元素和一个函数指针(指向处理数据元素的函数),可以将代码与数据关联起来.83 .数组可以通过存储供程序内的抽象

13、机(abstractmachine)或虚拟机(virtualmachine)使用的数据或代码,控制程序的运作.84 .可以将表达式sizeof(x)/sizeof(x0)理解为数组x中元素的个数.85 .如果结构中含有指向结构自身|名为next的元素,一般说来,该结构定义的是单向链表的结点.86 .指向链表结点的持久性(如全局|静态或在堆上分配)指针常常表示链表的头部.87 .包含指向自身的next和prev指针的结构可能是双向链表的结点.88 .理解复杂数据结构的指针操作可以将数据元素画为方框|指针画为箭头.89 .递归数据结构经常用递归算法来处理.90 .重要的数据结构操作算法一般用函数参

14、数或模板参数来参数化91 .图的结点常常顺序地存储在数组中,链接到链表中,或通过图的边链接起来.92 .图中的边一般不是隐式地通过指针,就是显式地作为独立的结构来表示.93 .图的边经常存储为动态分配的数组或链表,在这两种情况下,边都锚定在图的结点上.94 .在无向图中,表达数据时应该将所有的结点看作是等同的,类似地,进行处理任务的代码也不应该基于它们的方向来区分边95 .在非连通图中,执行遍历代码应该能够接通孤立的子图.96 .处理包含回路的图时,遍历代码应该避免在处理图的回路进入循环97 .复杂的图结构中,可能隐藏着其他类型的独立结构.+第五章:高级控制流程+98 .采用递归定义的算法和数

15、据结构经常用递归的函数定义来实现99 .推理递归函数时,要从基准落伍测试开始,并认证每次递归调用如何逐渐接近非递归基准范例代码.100 .简单的语言常常使用一系列遵循该语言语法结构的函数进行语法分析101 .推理互递归函数时,要基于底层概念的递归定义.102 .尾递归调用等同于一个回到函数开始处的循环103 .将throws子句从方法的定义中移除,然后运行Java编译器对类的源代码进行编译,就可以容易地找到那些可能隐式地生成异常的方法104 .在多处理器计算机上运行的代码常常围绕进程或线程进行组织105 .工作群并行模型用于在多个处理器间分配工作,或者创建一个任务池,然后将大量需要处理标准化的

16、工作进行分配.106 .基于线程的管理者/工人并行模型一般将耗时的或阻塞的操作分配给工人子任务,从而维护中心任务的响应性.107 .基于进程的管理者/工人并行模型一般用来重用现有的程序,或用定义良好的接口组织和分离粗粒度的系统模块.108 .基于流水线的并行处理中,每个任务都接收到一些输入,对它们进行一些处理,并将生成的输出传递给下一个任务,进行不同的处理.109 .竞争条件很难捉摸,相关的代码常常会将竞争条件扩散到多个函数或模块;因而,很难隔离由于竞争条件导致的问题.110 .对于出现在信号处理器中的数据结构操彳代码和库调用要保持高度警惕111 .在阅读包含宏的代码时,要注意,宏既非函数,也

17、非语句.112 .dowhile(0)块中的宏等同于控制块中的语句.113 .宏可以访问在它的使用点可见的所有局部变量114 .宏调用可改变参数的值115 .基于宏的标记拼接能够创建新的标记符.+第六章:应对大型项目+116 .我们可以通过浏览项目的源代码树一包含项目源代码的层次目录结构,来分析一个项目的组织方式.源码树常常能够反映出项目在构架和软件过程上的结构117 .应用程序的源代码树经常是该应用程序的部署结构的镜像118 .不要被庞大的源彳t码集合吓倒;它们一般比小型的专门项目组织得更出色.119 .当您首次接触一个大型项目时,要花一些时间来熟悉项目的目录树结构.120 .项目的源代码远

18、不只是编译后可以获得可执行程序的计算机语言指令;一个项目的源码树一般还包括规格说明|最终用户和开发人员文档|测试脚本|多媒体资源|编译工具|例子|本地化文件|修订历史|安装过程和许可信息.121 .大型项目的编译过程一般声明性地借助依赖关系来说明.依赖关系由工具程序,如make及其派生程序,转换成具体的编译行动.122 .大型项目中,制作文件常常由配置步骤动态地生成;在分析制作文件之前,需要先执行项目特定的配置.123 .检查大型编译过程的各个步骤时,可以使用make程序的-n开关进行预演.124 .修订控制系统提供从储存库中获取源代码最新版本的方式125 .可以使用相关的命令,显示可执行文件

19、中的修订标识关键字,从而将可执行文件与它的源代码匹配起来.126 .使用修订日志中出现的bug跟踪系统内的编号,可以在bug跟踪系统的数据库中找到有关的问题的说明.127 .可以使用修订控制系统的版本储存库,找出特定的变更是如何实现的.128 .定制编译工具用在软件开发过程的许多方面,包括配置|编译过程管理|代码的生成|测试和文本编制.129 .程序的调试输出可以帮助我们理解程序控制流程和数据元素的关键部分130 .跟踪语句所在的地点一般也是算法运行的重要部分131 .可以用断言来检验算法运作的步骤|函数接收的参数|程序的控制流程|底层硬件的属性和测试用例的结果.132 .可以使用对算法进行检

20、验的断言来证实您对算法运作的理解,或将它作为推理的起点.133 .对函数参数和结果的断言经常记录了函数的前置条件和后置条件134 .我们可以将测试整个函数的断言作为每个给定函数的规格说明135 .测试用例可以部分地代替函数规格说明.136 .可以使用测试用例的输入数据对源代码序列进行预演+第七章:编码规范和约定+137 .了解了给定代码库所遵循的文件组织方式后,就能更有效率地浏览它的源代码.138 .阅读代码时,首先要确保您的编辑器或优美打印程序的tab设置,与代码遵循的风格规范一致.139 .可以使用代码块的缩进,快速地掌握代码的总体结构.140 .对编排不一致的代码,应该立即给予足够的警惕

21、.141 .分析代码时,对标记为XXX,FIXME和TODO的代码序列要格外注意:错误可能就潜伏在其中.142 .常量使用大写字母命名,单词用下划线分隔.143 .在遵循Java编码规范的程序中,包名(packagename)总是从一个顶级的域名开始(例如,org,com),类名和接口名由大写字母开始,方法和变量名由小写字母开始.144 .用户界面控件名称之前的匈牙利记法的前缀类型标记可以帮助我们确定它的作用145 .不同的编程规范对可移植构造的构成有不同的主张146 .在审查代码的可移植性,或以某种给定的编码规范作为指南时,要注意了解规范对可移植性需求的界定与限制.147 .如果GUI功能都

22、使用相应的编程结构来实现,则通过代码审查可以轻易地验证给定用户界面的规格说明是否被正确地采用.148 .了解项目编译过程的组织方式与自动化方式之后,我们就能够快速地阅读与理解对应的编译规则.149 .当检查系统的发布过程时,常常可以将相应发行格式的需求作为基准.+第八章:文档+150 .阅读代码时,应该尽可能地利用任何能够得到的文档.151 .阅读一小时代码所得到的信息只不过相当于阅读一分钟文档152 .使用系统的规格说明文档,了解所阅读代码的运行环境.153 .软件需求规格说明是阅读和评估代码的基准.154 .可以将系统的设计规格说明作为认知代码结构的路线图,阅读具体代码的指引.155 .测

23、试规格说明文档为我们提供可以用来对代码进行预演的数据156 .在接触一个未知系统时,功能性的描述和用户指南可以提供重要的背景信息,从而更好地理解阅读的代码所处的上下文.157 .从用户参考手册中,我们可以快速地获取,应用程序在外观与逻辑上的背景知识,从管理员手册中可以得知代码的接口|文件格式和错误消息的详细信息.158 .利用文档可以快捷地获取系统的概况,了解提供特定特性的代码.159 .文档经常能够反映和提示出系统的底层结构.160 .文档有助于理解复杂的算法和数据结构.161 .算法的文字描述能够使不透明(晦涩,难以理解)的代码变得可以理解.162 .文档常常能够阐明源代码中标识符的含义.163 .文档能够提供非功能性需求背后的理论基础.164 .文档还会说明内部编程接口.165 .由于文档

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论