gnu coreutils-4.5.1 uniq.c代码分析


今天看了会书,有一人说,如果感兴趣,就会主动研究,就不会没有基础了,感觉很好玩。我对代码有兴趣,也不是零基础了。
但每回看到他们的代码,我总是信息被打击,他们的代码写得真好。
先把按行数显示代码的程序弄成一个脚本:
wc -l *.c | sort -n -k1 | head -$1
保存成一个文件,需要显示的行数作为参数传进来。
比如保存为lsc.sh
./lsc.sh 50
就看到前50个代码量小的文件。
uniq.c很好用的。用法不表。直接看代码
其中一个宏很好玩
#define SWAP_LINES(A, B)   \
  do      \
    {      \
      struct linebuffer *_tmp;   \
      _tmp = (A);    \
      (A) = (B);    \
      (B) = _tmp;    \
    }      \
  while (0)
当时我在想,不就是交换A,B吗,为什么写成循环。自己测试一下,因为这个循环只会执行一次,为什么写成循环。
看来,作者是为了看上去漂亮。
几天不看代码,就有些生疏了,今天闹钟,不用手机当闹钟了。
翻到前面没有感觉,看到main才有些感觉。
 check_file (file[0], file[1]);
当时我在想,如何写file[0],file[1]赋值的呢?
没看懂这段,自己测试下uniq用法,发现主要是file[0]起作用,也就没细究了。
接着分析check_file
先打开文件,然后读到行里。
thisline
prevline
这两个变量有意思。
程序中有一个大的if语句,第二个分支太麻烦,我只看了第一个
 if (mode == output_all && countmode == count_none)
为此我建立一个文件t01
a
a
b
b
b
c
在if的第一分支中加打印语句,
sudo make
./uniq t01
发现果然打印语句生效了。
再分析这个循环。
      while (!feof (istream))
 {
   char *thisfield;
   size_t thislen;
   if (readline (thisline, istream) == 0)
     break;
   thisfield = find_field (thisline);
   thislen = thisline->length - 1 - (thisfield - thisline->buffer);
   if (prevline->length == 0
       || different (thisfield, prevfield, thislen, prevlen))
     {
       fwrite (thisline->buffer, sizeof (char),
        thisline->length, ostream);
       SWAP_LINES (prevline, thisline);
       prevfield = thisfield;
       prevlen = thislen;
     }
 大致看明白了。从输入文件中读,直到读完为止
  先读一行
  find_field函数没看懂,好象是取到比较两行是否相同的标准
  再判断thisline中的thisfile与prevline中的prevfield是否相等。
  如果不相等,就打印出来,再交换prevline,thisline
  (其实只要把prevline<===thisline ,把prevline的值更新为thisline就可以了,完全不用交换。)
然后 再读读different函数,
开始总是看不懂,没看到它比较呀,后来才想明白。
 return oldlen != newlen || memcasecmp (old, new, oldlen);
 其实就是在比较了,如果字串长度不等,两字串肯定不同。如果字串长度相等,再调用 memcasecmp函数比较,我也懒得查函数,就象看古文一样,猜猜。
但此函数中前面两个if语句就不明白了。
 if (check_chars < oldlen)
    oldlen = check_chars;
  if (check_chars < newlen)
    newlen = check_chars;
  完全搞不明白为什么这样写?
如果要找到小的那个值,好象方向搞反了。这个函数先读到这儿。感觉使用命令比读代码爽多了。

猜你喜欢

转载自blog.csdn.net/woshiyilitongdouzi/article/details/80398878