ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:34.13KB ,
资源ID:5021199      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5021199.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(如何阅读原代码.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

如何阅读原代码.docx

1、如何阅读原代码如何阅读原代码阅读代码作为开发人员是一件经常要做的事情。一个是学习新的编程语言的时候通过阅读别人的代码是一个最好的学习方法,另外是积累编程经验。如果你有机会阅读一些操作系统的代码会帮助你理解一些基本的原理。还有就是在你作为一个质量保证人员或一个小领导的时候如果你要做白盒测试的时候没有阅读代码的能力是不能完成相应的任务。最后一个就是如果你中途接手一个项目的时候或给一个项目做售后服务的时候是要有阅读代码的能力的。收集所有可能收集的材料阅读代码要做的第一件事情是收集所有和项目相关的资料。比如你要做一个项目的售后服务,那么你首先要搞明白项目做什么用的,那么调研文档、概要设计文档、详细设计

2、文档、测试文档、使用手册都是你要最先搞到手的。如果你是为了学习那么尽量收集和你的学习有关的资料,比如你想学习linux的文件系统的代码,那最好要找到linux的使用手册、以及文件系统设计的方法、数据结构的说明。(这些资料在书店里都可以找到)。材料的种类分为几种类型1.基础资料。比如你阅读turbo / c2的源代码你要有turbo c2的函数手册,使用手册等专业书籍,msc 6.0或者java 的话不但要有函数手册,还要有类库函数手册。这些资料都是你的基础资料。另外你要有一些关于uml的资料可以作为查询手册也是一个不错的选择2.和程序相关的专业资料。每一个程序都是和相关行业相关的。比如我阅读过

3、一个关于气象分析方面的代码,因为里边用到了一个复杂的数据转换公式,所以不得不把自己的大学时候课本 找出来来复习一下高等数学的内容。如果你想阅读linux的文件管理的代码,那么找一本讲解linux文件系统的书对你的帮助会很大。3.相关项目的文档资料这一部分的资料分为两种,一个相关行业的资料,比如你要阅读一个税务系统的代码那么有一些财务/税务系统的专业资料和国家的相关的法律、法规的资料是 必不可少的。此外就是关于这个项目的需求分析报告、概要设计报告、详细设计报告,使用手册、测试报告等,尽量多收集对你以后的代码阅读是很重要的知识准备了解基础知识,不要上来就阅读代码,打好基础可以做到事半功倍的效果留备

4、份,构造可运行的环境代码拿到手之后的第一件事情是先做备份,最好是刻在一个光盘上,在代码阅读的时候一点不动代码是很困难的一件事情,特别是你要做一些修改性或增强性维护的时候。而一旦做修改就可能发生问题,到时候要恢复是经常发生的事情,如果你不能很好的使用版本控制软件那么先留一个备份是一个最起码的要求了。在做完备份之后最好给自己构造一个可运行的环境,当然可能会很麻烦,但可运行代码和不可运行的代码阅读起来难度会差很多的。所以多用一点时间搭建一个环境是很值得的,而且我们阅读代码主要是为了修改其中的问题或做移植操作。不能运行的代码除了可以学到一些技术以外,用处有限。找开始的地方做什么事情都要知道从那里开始,

5、读程序也不例外。在c语言里,首先要找到main()函数,然后逐层去阅读,其他的程序无论是vb、delphi都要首先找到程序头,否则你是很难分析清楚程序的层次关系。分层次阅读在阅读代码的时候不要一头就扎下去,这样往往容易只见树木不见森林,阅读代码比较好的方法有一点象二叉树的广度优先的遍历。在程序主体一般会比较简 单,调用的函数会比较少,根据函数的名字以及层次关系一般可以确定每一个函数的大致用途,将你的理解作为注解写在这些函数的边上。当然很难一次就将全部注 解都写正确,有时候甚至可能是你猜测的结果,不过没有关系这些注解在阅读过程是不断修正的,直到你全部理解了代码为止。一般来说采用逐层阅读的方法可以

6、是 你系统的理解保持在一个正确的方向上。避免一下子扎入到细节的问题上。在分层次阅读的时候要注意一个问题,就是将系统的函数和开发人员编写代码区分开。在 c, c+,java ,delphi中都有自己的系统函数,不要去阅读这些系统函数,除非你要学习他们的编程方法,否则只会浪费你的时间。将系统函数表示出来,注明它们的作用 即可,区分系统函数和自编函数有几个方法,一个是系统函数的编程风格一般会比较好,而自编的函数的编程风格一般比较会比较差。从变量名、行之间的缩进、注 解等方面一般可以分辨出来,另外一个是象ms c6+会在你编程的时候给你生成一大堆文件出来,其中有很多文件是你用不到了,可以根据文件名来区

7、分一下时候是系统函数,最后如果你实在确定不了,那就 用开发系统的帮助系统去查一下函数名,对一下参数等来确定即可。写注解写注解是在阅读代码中最重要的一个步骤,在我们阅读的源代码一般来说是我们不熟悉的系统,阅读别人的代码一般会有几个问题,1搞明白别人的编程思想不 是一件很容易的事情,即使你知道这段程序的思路的时候也是一样。2阅读代码的时候代码量一般会比较大,如果不及时写注解往往会造成读明白了后边忘了前边的 现象。3阅读代码的时候难免会出现理解错误,如果没有及时的写注解很难及时的发现这些错误。4不写注解有时候你发生你很难确定一个函数你时候阅读过,它的功能是什么,经常会发生重复阅读、理解的现象。好了,

8、说一些写注解的基本方法:1猜测的去写,刚开始阅读一个代码的时候,你很难一下子就确定所有的函数的功能,不妨采用采用猜测的方法去写注解,根 据函数的名字、位置写一个大致的注解,当然一般会有错误,但你的注解实际是不但调整的,直到最后你理解了全部代码。2按功能去写,别把注解写成语法说明 书,千万别看到fopen就写打开文件,看到fread就写读数据,这样的注解一点用处都没有,而应该写在此处开发参数配置文件(*。dat)读出 系统初始化参数。,这样才是有用的注解。3在写注解的使用另外要注意的一个问题是分清楚系统自动生成的代码和用户自 己开发的代码,一般来说没有必要写系统自动生成的代码。象delphi的代

9、码,我们往往要自己编写一些自己的代码段,还要对一些系统自动生成的代码段进行 修改,这些代码在阅读过程是要写注解的,但有一些没有修改过的自动生成的代码就没有必要写注解了。4在主要代码段要写较为详细的注解。有一些函数或类在程 序中起关键的作用,那么要写比较详细的注解。这样对你理解代码有很大的帮助。5对你理解起来比较困难的地方要写详细的注解,在这些地方往往会有一些编程的技巧。不理解这些编程技巧对你以后的理解或移植会有问题。6写中文注解。如果你的英文足够的好,不用看这条了,但很多的人英文实在不怎么样,那就写中文注解吧,我们写注解是为了加快自己的理解速度。中文在大多数的时候比英文更适应中国人。与其写一些

10、谁也看不懂的英文注解还不如不写。重复阅读一次就可以将所有的代码都阅读明白的人是没有的。至少我还没有遇到过。反复的去阅读同一段代码有助于得代码的理解。一般来说,在第一次阅读代码的时候 你可以跳过很多一时不明白的代码段,只写一些简单的注解,在以后的重复阅读过程用,你对代码的理解会比上一次理解的更深刻,这样你可以修改那些注解错误的 地方和上一次没有理解的对方。一般来说,对代码阅读3,4次基本可以理解代码的含义和作用。运行并修改代码如果你的代码是可运行的,那么先让它运行起来,用单步跟踪的方法来阅读代码,会提高你的代码速度。代码通过看中间变量了解代码的含义,而且对 以后的修改会提供很大的帮助用自己的代码

11、代替原有代码,看效果,但在之前要保留源代码600行的一个函数,阅读起来很困难,编程的人不是一个好的习惯。在阅读这个代码的时候将代码进行修改,变成了14个函数。每一个大约是40-50 行左右.第一章:导论 1.要养成一个习惯,经常花时间阅读别人编写的高品质代码. 2.要有选择地阅读代码,同时,还要有自己的目标.您是想学习新的模式|编码风格|还是满足某些需求的方法. 3.要注意并重视代码中特殊的非功能性需求,这些需求也许会导致特殊的实现风格. 4.在现有的代码上工作时,请与作者和维护人员进行必要的协调,以避免重复劳动或产生厌恶情绪. 5.请将从开放源码软件中得到的益处看作是一项贷款,尽可能地寻找各

12、种方式来回报开放源码社团. 6.多数情况下,如果您想要了解别人会如何完成这个功能呢?,除了阅读代码以外,没有更好的方法. 7.在寻找bug时,请从问题的表现形式到问题的根源来分析代码.不要沿着不相关的路径(误入歧途). 8.我们要充分利用调试器|编译器给出的警告或输出的符号代码|系统调用跟踪器|数据库结构化查询语言的日志机制|包转储工具和Windows的消息侦查程序,定出的bug的位置. 9.对于那些大型且组织良好的系统,您只需要最低限度地了解它的全部功能,就能够对它做出修改. 10.当向系统中增加新功能时,首先的任务就是找到实现类似特性的代码,将它作为待实现功能的模板. 11.从特性的功能描

13、述到代码的实现,可以按照字符串消息,或使用关键词来搜索代码. 12.在移植代码或修改接口时,您可以通过编译器直接定位出问题涉及的范围,从而减少代码阅读的工作量. 13.进行重构时,您从一个能够正常工作的系统开始做起,希望确保结束时系统能够正常工作.一套恰当的测试用例(testcase)可以帮助您满足此项约束. 14.阅读代码寻找重构机会时,先从系统的构架开始,然后逐步细化,能够获得最大的效益. 15.代码的可重用性是一个很诱人,但难以理解与分离,可以试着寻找粒度更大一些的包,甚至其他代码. 16.在复查软件系统时,要注意,系统是由很多部分组成的,不仅仅只是执行语句.还要注意分析以下内容:文件和

14、目录结构|生成和配置过程,用户界面和系统的文档. 18.可以将软件复查作为一个学习|讲授|援之以手和接受帮助的机会. + 第二章:基本编程元素 + 19.第一次分析一个程序时,main是一个好的起始点. 20.层叠if-elseif-.-else序列可以看作是由互斥选择项组成的选择结构. 21.有时,要想了解程序在某一方面的功能,运行它可能比阅读源代码更为恰当. 22.在分析重要的程序时,最好首先识别出重要的组成部分. 23.了解局部的命名约定,利用它们来猜测变量和函数的功能用途. 24.当基于猜测修改代码时,您应该设计能够验证最初假设的过程.这个过程可能包括用编译器进行检查|引入断言|或者执

15、行适当的测试用例. 25.理解了代码的某一部分,可能帮助你理解余下的代码. 26.解决困难的代码要从容易的部分入手. 27.要养成遇到库元素就去阅读相关文档的习惯;这将会增强您阅读和编写代码的能力. 28.代码阅读有许多可选择的策略:自底向上和自顶向下的分析|应用试探法和检查注释和外部文档,应该依据问题的需要尝试所有这些方法. 29.for(i=0;in;i+)形式的循环执行n次;其他任何形式都要小心. 30.涉及两项不等测试(其中一项包括相等条件)的比较表达式可以看作是区间成员测试. 31.我们经常可以将表达式应用在样本数据上,借以了解它的含义. 32.使用DeMorgan法则简化复杂的逻辑

16、表达式. 33.在阅读逻辑乘表达式时,问题可以认为正在分析的表达式以左的表达式均为true;在阅读逻辑和表达式时,类似地,可以认为正在分析的表达式以左的表达式均为false. 34.重新组织您控制的代码,使之更为易读. 35.将使用条件运行符?:的表达式理解为if代码. 36.不需要为了效率,牺牲代码的易读性. 37.高效的算法和特殊的优化确实有可能使得代码更为复杂,从而更难理解,但这并不意味着使代码更为紧凑和不易读会提高它的效率. 38.创造性的代码布局可以用来提高代码的易读性. 39.我们可以使用空格|临时变量和括号提高表达式的易读性. 40.在阅读您所控制的代码时,要养成添加注释的习惯.

17、 41.我们可以用好的缩进以及对变量名称的明智选择,提高编写欠佳的程序的易读性. 42.用diff程序分析程序的修订历史时,如果这段历史跨越了整体重新缩排,常常可以通过指定-w选项,让diff忽略空白差异,避免由于更改了缩进层次而引入的噪音. 43.do循环的循环体至少执行一次. 44.执行算术运算时,当b=2n-1时,可以将a&b理解为a%(b+1). 45.将an理解为a/k,k=2n. 47.每次只分析一个控制结构,将它的内容看作是一个黑盒. 48.将每个控制结构的控制表达式看作是它所包含代码的断言. 49.return,goto,break和continue语句,还有异常,都会影响结构

18、化的执行流程.由于这些语句一般都会终止或重新开始正在进行的循环,因此要单独推理它们的行为. 50.用复杂循环的变式和不变式,对循环进行推理. 51.使用保持含义不变的变换重新安排代码,简化代码的推理工作. + 第三章:高级C数据类型 + 52.了解特定语言构造所服务的功能之后,就能够更好地理解使用它们的代码. 53.识别并归类使用指针的理由. 54.在C程序中,指针一般用来构造链式数据结构|动态分配的数据结构|实现引用调用|访问和迭代数据元素|传递数组参数|引用函数|作为其他值的别名|代表字符串|以及直接访问系统内存. 55.以引用传递的参数可以用来返回函数的结果,或者避免参数复制带来的开销.

19、 56.指向数组元素地址的指针,可以访问位于特定索引位置的元素. 57.指向数组元素的指针和相应的数组索引,作用在二者上的运算具有相同的语义. 58.使用全局或static局部变量的函数大多数情况都不可重入(reentrant). 59.字符指针不同于字符数组. 60.识别和归类应用结构或共用体的每种理由. 61.C语言中的结构将多个数据元素集合在一起,使得它们可以作为一个整体来使用,用来从函数中返回多个数据元素|构造链式数据结构|映射数据在硬件设备|网络链接和存储介质上的组织方式|实现抽象数据类型|以及以面向对象的方式编程. 62.共用体在C程序中主要用于优化存储空间的利用|实现多态|以及访

20、问数据不同的内部表达方式. 63.一个指针,在初始化为指向N个元素的存储空间之后,就可以作为N个元素的数组来使用. 64.动态分配的内在块可以电焊工地释放,或在程序结束时释放,或由垃圾回收器来完成回收;在栈上分配的内存块当分配它的函数退出后释放 65.C程序使用typedef声明促进抽象,并增强代码的易读性,从而防范可移植性问题,并模拟C+和Java的类声明行为. 66.可以将typedef声明理解成变量定义:变量的名称就是类型的名称;变量的类型就是与该名称对应的类型. + 第四章:C数据结构 + 67.根据底层的抽象数据类型理解显式的数据结构操作. 68.C语言中,一般使用内建的数组类型实现

21、向量,不再对底层实现进行抽象. 69.N个元素的数组可以被序列for(i=0;iN;i+)完全处理;所有其他变体都应该引起警惕. 70.表达式sizeof(x)总会得到用memset或memcpy处理数组x(不是指针)所需的正确字节数. 71.区间一般用区间内的第一个元素和区间后的第一个元素来表示. 72.不对称区间中元素的数目等于高位边界与低位边界的差. 73.当不对称区间的高位边界等于低位边界时,区间为空. 74.不对称区间中的低位边界代表区间的第一个元素;高位边界代表区间外的第一个元素. 75.结构的数组常常表示由记录和字段组成的表. 76.指向结构的指针常常表示访问底层记录和字段的游标

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

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

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

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

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

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

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

29、配起来. 126.使用修订日志中出现的bug跟踪系统内的编号,可以在bug跟踪系统的数据库中找到有关的问题的说明. 127.可以使用修订控制系统的版本储存库,找出特定的变更是如何实现的. 128.定制编译工具用在软件开发过程的许多方面,包括配置|编译过程管理|代码的生成|测试和文档编制. 129.程序的调试输出可以帮助我们理解程序控制流程和数据元素的关键部分. 130.跟踪语句所在的地点一般也是算法运行的重要部分. 131.可以用断言来检验算法运作的步骤|函数接收的参数|程序的控制流程|底层硬件的属性和测试用例的结果. 132.可以使用对算法进行检验的断言来证实您对算法运作的理解,或将它作为推理的起点. 133.对函数参数和结果的断言经常记录了函数的前置条件和后置条件. 134.我们可以将测试整个函数的断言作为每个给定函数的规格说明. 135.测试用例可以部分地代替函数规格说明. 136.可以使用测试用例的输入数据对源代码序列进行预演. + 第七章:编码规范和约定

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1