以下内容主要是针对C语言或类C的语言为主来说的
无论阅读什么代码,基础和前提都是要掌握代码中体现的计算机基础知识,比如内核知识,操作系统知识,编程语言基本概念等。但阅读代码前,不一定要先去学会这些知识才能看代码。
其次,就是要先了解和学习一些这套代码在功能或者业务上所体现的概念与知识,这些概念很多是基于计算机基础的软硬件概念之上,产生的新概念而已,可以通过看注释或者查资料等方式来掌握这些基本概念,否则单纯的直接先看代码很难知道这些概念是什么意思,就更谈不上往下去分析这些概念之间的关系与如何运用它们了。
第三,了解了以上概念后,当然可以继续看资料来学习代码的逻辑或者概念之间的关系,但如果想锻炼代码阅读能力的话,最好还是在知道了基本概念以后,自己通过阅读代码来解析概念之间的联系和业务逻辑等等,以此来提高代码阅读能力,然后写出自己的学习心得。
那么如何阅读代码呢?陆续总结出以下几个心得体会:
1.要搞清楚各个文件之间的关系:
方法是通过看Makefile等编译文件来分析,或者根据文件名来猜测与验证。
2.要搞清楚数据结构和数据结构之间的关系:
方法就是将重点数据结构中的重点成员挑出来,通过画图来理清各个数据结构之间的关系。 首先要判断出重点的数据结构是哪些,然后尽量了解这几个重点数据结构之间的关系,并通过他们的关系大胆的猜测出各个模块的大致关系,然后通过继续阅读代码来验证自己的猜测,并不断往复的修正结论。
3.要搞清楚函数之间的调用关系:
一个文件中的函数可能很多,刚打开文件时可能找不到头绪,不知道从哪开始看,所以不断总结下文件中的函数的组织形式关系都有哪些,阅读代码时可以对号入座看看属于哪一种关系或哪几种的组合:
(1)一个或几个类似主函数的函数,其他的函数在这几个“主”函数里被调用。(这种情况时,主要函数一般会写在相对靠下面的部分,只能自己去找了)
(2)一组或几组函数是被注册的回调函数,在这套代码的整个框架机制中,这些回调函数会被调用。(这种情况时,从代码工具比如SI,会看到有函数指针结构体定义)
(3)所有的函数都是单个的工具类函数,被其他地方随处调用。(这种情况时,函数的独立性明显)
(4)。。。(持续总结更新)
4.如果代码是一套库函数,或者类似内核驱动等将会被其他程序所调用的,那么可以从调用他们的这个代码入手来分析,因为“使用方”的代码包含了如何去使用这套代码的逻辑和步骤,而这个逻辑和步骤正是我们分析的这套代码的最主要目的,这就好比一团乱如麻的线团如何理清头绪呢,当然是先找到每根线的线头,而线头一定是包含在使用方的代码里面的。
总结出两点:
因为一套代码基本就是由数据结构和函数两部分组成的,函数是逻辑处理,基本是为了处理数据结构,数据结构是各种关系的体现,所以总结出如何看代码的两个办法如下:
(1). 顺藤摸瓜:函数是藤,数据结构中的成员是瓜,根据函数内部的对数据的处理,来判断出各数据结构之间的关系。本方法适用于数据结构多而复杂,无法直接通过数据结构判断出关系的情况。
(2).看瓜找藤:当数据结构比较容易直接看出关系时,根据这些关系去找搭建出这些关系的函数。
函数间以及函数内部作为藤来说,可以看成只是对瓜进行处理的人类逻辑的体现,而瓜才是真正要处理的目的,所以从这个意义上来说,对作为数据结构的瓜的分析可能更为重要,甚至如果阅读过很多代码有了经验以后,可能根据瓜的结构就能猜测出一些藤将实现的逻辑,或者说在阅读藤之前你就应该相信藤的内容一定是为了对瓜的处理而服务的。
所以在设计软件时,先设计出一套瓜的结构可能更为重要。
以上方法可以递归使用,也就是说对于一个瓜如果比较复杂,也可以将这个瓜看成是一个瓜田,然后使用上面的方法继续分析。在分析代码的过程中,还是需要以很多基础知识、基础软件框架为前提的,所以掌握的基础越丰厚,看代码会越容易。所以要两手努力,一边丰厚基础知识,一边找代码实践。