2009年6月24日水曜日

C 言語の話#4 リスト

リストを林檎生活100: C 言語の話#3 オブジェクト指向プログラミング?のように実装.まあ,スタック的操作しか実装してないけどwイテレータもやればできるもんだね.
/* main.c */
#include <stdio.h>
#include <string.h>
#include "book.h"
#include "list.h"

int main(void)
{
List *books;
Book *book;
Iterator *it;

books = newList();

books->push(books, newBook("伝奇集", "J.L. ボルヘス"));
books->push(books, newBook("ぼく、オタリーマン。", "よしたに"));
books->push(books, newBook("ブタのいどころ", "小泉吉宏"));

it = newIterator(books);
while (it->hasNext(it)) {
book = it->next(it);
printf("%s\t%s\n", book->getTitle(book), book->getAuthor(book));
}
deleteIterator(it);

while ((book = books->pop(books)) != NULL)
deleteBook(book);

deleteList(books);

return 0;
}
/* list.h */
#ifndef __LIST_H__
#define __LIST_H__

typedef struct _List List;
typedef struct _Iterator Iterator;
typedef struct _Element Element;

struct _List {
Element *first;
int ((*push)(List *list, void *data));
void *((*pop)(List *list));
};

struct _Iterator {
Element *e;
int ((*hasNext)(const Iterator *it));
void *((*next)(Iterator *it));
};

List *newList(void);
void deleteList(List *list);

Iterator *newIterator(List *list);
void deleteIterator(Iterator *it);

#endif /* __LIST_H__ */
/* list.c */
#include
#include
#include "list.h"

struct _Element {
Element *next;
void *data;
};

int list_push(List *list, void *data);
void *list_pop(List *list);

int iterator_hasNext(const Iterator *it);
void *iterator_next(Iterator *it);

Element *newElement(Element *e, void *data);
void deleteElement(Element *e);

List *newList(void)
{
List *list;

list = (List *)malloc(sizeof(List));
if (list == NULL) {
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}

list->first = NULL;

list->push = list_push;
list->pop = list_pop;

return list;
}

void deleteList(List *list)
{
free(list);
}

int list_push(List *list, void *data)
{
Element *e;

e = newElement(list->first, data);
if (e == NULL) {
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return -1;
}

list->first = e;

return 0;
}

void *list_pop(List *list)
{
Element *e;
void *data;

if (list->first == NULL)
return NULL;

e = list->first;
data = e->data;
list->first = e->next;

deleteElement(e);

return data;
}

Iterator *newIterator(List *list)
{
Iterator *it;

it = (Iterator *)malloc(sizeof(Iterator));
if (it == NULL) {
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}

it->e = list->first;

it->hasNext = iterator_hasNext;
it->next = iterator_next;

return it;
}

void deleteIterator(Iterator *it)
{
free(it);
}

int iterator_hasNext(const Iterator *it)
{
return it->e != NULL ? 1 : 0;
}

void *iterator_next(Iterator *it)
{
void *data;

if (!iterator_hasNext(it))
return NULL;

data = it->e->data;
it->e = it->e->next;

return data;
}

Element *newElement(Element *next, void *data)
{
Element *e;

e = (Element *)malloc(sizeof(Element));
if (e == NULL) {
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}

e->next = next;
e->data = data;

return e;
}

void deleteElement(Element *e)
{
free(e);
}

0 件のコメント: