1. 程式人生 > >coreutils4.5.1 uniq.c原始碼分析1

coreutils4.5.1 uniq.c原始碼分析1

uniq.c這個檔案其實沒讀懂,不過從程式中發現了幾個支點,下次再細細品。
第一。交換兩行的寫法。

#define SWAP_LINES(A, B)            \
  do                        \
    {                        \
      struct linebuffer *_tmp;            \
      _tmp = (A);                \
      (A) = (B);                \
      (B) = _tmp;                \
    }                        \
  while (0)

作者定義一個巨集,而且而寫一個只執行一次的迴圈,奇怪吧。我看到時,也算服了。你完全可以寫成一個塊語句呀,加上do while迴圈,豈不是畫蛇添足。

#define SWAP_LINES(A, B)            \
                          \
    {                        \
      struct linebuffer *_tmp;            \
      _tmp = (A);                \
      (A) = (B);                \
      (B) = _tmp;                \
    }                        \
 寫成這樣,難道不行嗎?真是!
第二、字串陣列
static char const *const delimit_method_string[] =
{
  "none", "prepend", "separate", 0
};
作者用末尾的0表示字串結束了,這種技巧也很有用。

第三、用於比較的那段

      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;
        }
    }
    我的理解是,作者先定義兩個串,prev表示前面一串,this表示當前串,當前串和前一串不等時,就要列印結構,並對prev前一串相關值進行更新。大體是這樣。