はじめての C

リンクリスト 5
ヘッダファイルに 記されていた 4つの 関数は、tutorial の 最後にある List.c に そのコードが 書かれている (実際の 関数は 4つ じゃなくて 6つ)。

#include /* free(), abort() に必要 */
#include /* assert() に必要 */
#include "List.h" /* prelist.h では なかった ! */

/* 次の 2つの 関数は このソースファイル内のみで 使われる */

static void ins_before(Element iter, Element item)
{
assert(iter != NULL);
assert(item != NULL);
item->prev = iter->prev;
item->next = iter;
if (iter->prev != NULL)
item->prev->next = item;
iter->prev = item;
}

static void ins_after(Element iter, Element item)
{
assert(iter != NULL);
assert(item != NULL);
item->prev = iter;
item->next = iter->next;
if (iter->next != NULL)
iter->next->prev = item;
iter->next = item;
}

Element first(Element iter)
{
while (iter != NULL && iter->prev != NULL)
iter = iter->prev;
return iter;
}

Element last(Element iter)
{
while (iter != NULL && iter->next != NULL)
iter = iter->next;
return iter;
}

List add(List list, Element iter, Element item, Direction dir)
{
assert(item != NULL);
if (list == NULL) /* Empty list*/
list = item;
else {
if (iter == list && dir == BEFORE) /* before head */
ins_before(list, item);
list = item;
}
else {
if (dir == BEFORE) /* Before internal node */
ins_before(iter, item);
else /* After internal node */
ins_after(iter, item);
}
}
return list;
}

List rem(List list, Element iter)
{
assert(list != NULL)
assert(iter != NULL)
if (iter->prev != NULL)
iter->prev->next = iter->next;
if (iter->next != NULL)
iter->next->prev = iter->prev;
if (iter == list)
list = iter->next;
free(iter);
return list;
}

(注 1) assert - プログラムの バグを 調べるときに 使う 関数 (KandR 2nd p320)。
assert ( 評価式 )
評価式が 偽 (帰り値が 0) のときは、標準エラー出力で エラーメッセージを プリントする。
Assertion failed: 評価式, file ソースファイル名, line 行番号
その後、abort を 呼び出して 異常終了。
(注 2) static - 関数を static と 宣言すると、その名前は それが 宣言された ファイルの 外からは 見えなくなる (KandR 2nd p101)。