構造体の2つの宣言方法:スタックとスタック、およびデュアルチェーンテーブルへの応用

3625 ワード

『アルゴリズムの精解:C言語の説明』の二重チェーンテーブルchtblとredisの二重チェーンテーブルadlistを見ています.cコードの構想は基本的に一致していることが分かった.
ただし、チェーンテーブルの初期化は異なります
1.『アルゴリズム精解:C言語記述』スタイル
/*****************************************************************************
*                                                                            *
*  Define a structure for doubly-linked list elements.                       *
*                                                                            *
*****************************************************************************/

typedef struct DListElmt_ {

void               *data;
struct DListElmt_  *prev;
struct DListElmt_  *next;

} DListElmt;

/*****************************************************************************
*                                                                            *
*  Define a structure for doubly-linked lists.                               *
*                                                                            *
*****************************************************************************/

typedef struct DList_ {

int                size;

int                (*match)(const void *key1, const void *key2);
void               (*destroy)(void *data);

DListElmt          *head;
DListElmt          *tail;

} DList;

最初は構造体を定義してスタックにメモリを割り当て、後で構造体アドレスを渡します.
int main(int argc, char **argv) {

DList              list;
DListElmt          *element;

int                *data,
                   i;

/*****************************************************************************
*                                                                            *
*  Initialize the doubly-linked list.                                        *
*                                                                            *
*****************************************************************************/

dlist_init(&list, free);

Initの場合は構造体ポインタを渡し、直接値を付与します
void dlist_init(DList *list, void (*destroy)(void *data)) {

/*****************************************************************************
*                                                                            *
*  Initialize the list.                                                      *
*                                                                            *
*****************************************************************************/

list->size = 0;
list->destroy = destroy;
list->head = NULL;
list->tail = NULL;

return;

}

2.Redisのスタイル
Initの場合、スタックにメモリを動的に割り当て、構造体ポインタを返します.
/* Create a new list. The created list can be freed with
 * AlFreeList(), but private value of every node need to be freed
 * by the user before to call AlFreeList().
 *
 * On error, NULL is returned. Otherwise the pointer to the new list. */
list *listCreate(void)
{
    struct list *list;

    if ((list = zmalloc(sizeof(*list))) == NULL)
        return NULL;
    list->head = list->tail = NULL;
    list->len = 0;
    list->dup = NULL;
    list->free = NULL;
    list->match = NULL;
    return list;
}
typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct list {
    listNode *head;
    listNode *tail;
    void *(*dup)(void *ptr);
    void (*free)(void *ptr);
    int (*match)(void *ptr, void *key);
    unsigned long len;
} list;

一級ポインタと二級指および(void*)&二重チェーンテーブルへの応用を説明する[ここでは二重チェーンテーブルの削除を解析する]