積雲が映像制作したMV『RANGEFINDER』公開中
専門88IO

新明解C言語実践編の線形リストは難解

専門

新明解シリーズ、JavaやC言語と様々な入門書が揃っている。

正直中身は面白くない。特に入門編はサンプルコードの日本語は多いわ、やっていることが大して代わり映えしないわで面白くない。

入門書なので仕方がないにせよ、今回は実践編の1トピックで理解し難い仕様があった。

線形リストは下図の構造を持ったリストで先頭要素へのポインタを基軸に各ノードが次のノードのポインタを保持している。

サンプルコードにおいてノードは以下のような構造をしており、

typedef struct __node {
  int    no;             /* 会員番号 */
  char   name[NAMELEN];  /* 名前 */
  struct __node *next;   /* 後続ノードへのポインタ */

これの生成をリストへの追加を行う関数内で行ってしまっている。

void InsertNode(Node **top, int no, char *name) {
  Node *ptr= *top;
  *top = AllocNode();
  SetNode(*top, no, name, ptr);
}

実践編だろう?何故追加ノードを引数に取らずにプロパティを取るのか。これのせいでInsertNodeをはじめとしたユーティリティ(?)メソッドは軒並み{会員番号, 名前}のノードしか扱えない。{名前, 身長, 体重}を保持したかったら構造体だけでなく各関数も書き換える必要が出てくる。

この問題に拍車を掛けるのが補題となっている線形リストを用いたキューの実装。仕様も明示されていてこんな感じ。

int QueueEnque(Queue *q, Node *x);
Node *QueueDeque(Queue *q);

どうしてこっちはノードのポインタを渡すのか。せめて前項と仕様統一してくれ。結局、線形リストの実装で用いた関数群の多くは流用できなかった。

正直汎用性に欠ける。自分で一から書くことを目的としているのかもしれないが、この書籍は「実践編」であり既存の資源は再利用するべきだろう。できれば切り分けてより汎用的に使えるようにしたいが、生憎課題のひとつはサンプルコードの仕様に則り機能拡張を行うというもので持論とコンフリクトを起こしている。やっぱり苦手だ。

コメント

タイトルとURLをコピーしました