coreutils4.5.1代码阅读感想……代码编写的模式
看了ruby0.49,对比起来,感觉首先coreutils4.5.1能顺利的编译,真是太幸福了。虽然开始因为编译器版本高,折磨了一下,但后来,修改程序后,只要在src目录下sudo make一下,立即能看到效果,感觉太幸福了。而且coreutils都是些小程序,基本上一个文件对应一个命令,很容易理解。而象ruby0.49是个大程序了。理解起来,就难了。
今天我想总结一下,我看到的命令模式。
-----
先定义若干全局变量
再定义若干函数,在函数中使用到了全局变量
定义usage
再写main()
先是一段公共处理。
调用getopt进行命令选项的处理,同时设置全局变量
如果命令选项中有多个文件
调用函数,对每个文件进行处理。
----
基本上每个命令都是这个模式。看多了,也就熟悉了。我发现代码,要反复读,不要追求一次透彻理解。我基本把代码当小说读,先看大的情节,知道大的算法,明白后,再由粗到细。
比如,昨天看的那个comm.c
static int
compare_files (char **infiles)
根据两个文件当前行比较结果,如果两行相同,返回3,如果只有第1个文件有,返回1;如果只有第2个文件有,返回2.再调用
/* Output the line that is lesser. */
if (order == 0)
writeline (thisline[1], stdout, 3);
else if (order > 0)
writeline (thisline[1], stdout, 2);
else
writeline (thisline[0], stdout, 1);
进行写文件。其中writeline的写法特别难懂,
static void
writeline (const struct linebuffer *line, FILE *stream, int class)
{
switch (class)
{
case 1:
if (!only_file_1)
return;
break;
case 2:
if (!only_file_2)
return;
/* Print a TAB if we are printing lines from file 1. */
if (only_file_1)
putc ('\t', stream);
break;
case 3:
if (!both)
return;
/* Print a TAB if we are printing lines from file 1. */
if (only_file_1)
putc ('\t', stream);
/* Print a TAB if we are printing lines from file 2. */
if (only_file_2)
putc ('\t', stream);
break;
}
fwrite (line->buffer, sizeof (char), line->length, stream);
}
因此,我就忽略这个函数了,因为我知道其最终达到的效果,实现的大体逻辑知道了,这里两行比较的结果是1,2,3,又有only_file_1,only_fil2等变量的结果也是1,2,3,两个123把我弄糊糊了。我想要等我脑袋相当清醒时,我才会试着去理解它。
就象那个kmp算法一样,总是不理解。后来,看了用自动机进行模式匹配的算法,感觉这个kmp算法还是简单的,思想上转变了,就才有了一点点理解。明白计算next函数的概念,但为什么能这样算,还是不理解。
因此,我想,一定要照顾好自己,要活得足够长,你对一个问题思考得越长久,也就慢慢理解了。读代码,千万不能急呀。