)
最近我在阅读linux内核源码由于代码量太大了有成百个源文件源文件中有成千上万的函数我本来的计划是对每一个源文件中的函数自上而下粗略读一遍不会跳转到子函数中去看子函数是如何实现的理解里面的函数定义内容以便后面仿照内核源码写自己的代码也就是没有关心函数的调用关系函数被另外的函数是如何调用。虽然能够读懂函数内部实现方式提高了自己的c语言阅读水平不会被各种运算符号、各种分支循环结构给困住但是读下来总感觉收获不多最近也在思考造成这方面的原因。我感觉主要是与我现在这种自上而下的函数阅读的方式有关这样太低效了而且有“管中窥豹”的感觉。接下来需要改变我的这种阅读函数的方式我认为应该按照这样的步骤严格执行。1第一步理解函数的原型根据函数名理解实现什么功能根据参数列表理解所需数据可分为输入型参数、输出型参数根据返回值类型理解函数计算的结果。这个过程用到了vscode或者source insight这些IDE工具的跳转函数声明功能2第二步查看函数的调用关系函数被另外的那个函数调用的传递了哪些数据返回值给了哪个变量。这一步中形成了子函数原函数和父函数调用函数的调用关系。父函数可以作为子函数被另外的函数调用这样父函数调用子函数一级一级追踪下去就知道了整个网络的一部分。这个过程有点像地图的结构从一个地点到另外一个地点依次下去就得到整个地图的一条整线。如果将这一条条整线都看完了整个地图就看完了这就是“地图思维”。这个过程用到了vscode或者source insight这些IDE工具的查看所有引用、显示调用层次结构功能。3第三步一整条线路的调用关系捋清楚后就到了查看函数定义的内部实现这里就是进入函数内部一对大括号{}中去理解函数名代表的功能是如何实现的传递的参数是如何读写访问的返回值那个变量是如何写入有效数值并返回的。这个过程用到了vscode或者source insight这些IDE工具跳转到定义功能。我前期之所以感觉函数内部实现能够理解但是总感觉没什么收获就是因为忽略了第一步、第二步只做了第三步。就像是地图只看了某个地点而没看这个地点的调用关系。这样下来就只有一个局部的“点概念”而没有形成“线思维”以及最终的“图思维”。因此后面阅读剩余内核代码需要摒弃这种只顾“点概念”的思维具体表现为子上而下阅读函数遇到函数就进入看实现而忽略分析函数声明代表的三要素逐渐形成“线思维”和最终的“面思维”。引申在看源码过程中会遇到一些函数虽然定义了但是没有被其他函数调用或者就算被其他父函数调用了但是父函数没有被更上层的函数调用这就形成了断点函数这种情况也是在代码中经常看到断点函数占用一些空间不会有其他不良影响可以不用理会。