C语言回调函数实例


hash.h


typedef struct hash_item hash_item;


struct hash_item {
        void           *key;
        void           *data;
        hash_item      *next;
};


typedef struct hashing hashing;


struct hashing {
        int             length;
        hash_item     **list;


        int             (*hash_fun) (void *);
        int             (*key_cmp) (void *, void *);
        hash_item      *(*item_copy) (hash_item *);


        hashing        *(*hash_add) (hashing *, hash_item *);
        hash_item      *(*hash_get) (hashing *, void *);


};


hashing * init_hash(
          hashing *,
          int length,
          int (*) (void *),
          int (*) (void *, void *),
          hash_item * (*) (hash_item *) );


int str_hash_fun(void *, int);
int str_hash_key_cmp(void *, void *);
hashing *hash_add(hashing * self, hash_item *);

hash_item *hash_get(hashing * self, void *);


hash.c


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hash.h"


hashing * init_hash(
          hashing * self,
          int length,
          int (*hash_fun) (void *),
          int (*key_cmp) (void *, void *),
          hash_item * (*item_copy) (hash_item *))
{
        int i;


        assert(length >= 2);
        assert(hash_fun != NULL);
        assert(key_cmp != NULL);
        assert(item_copy != NULL);


        self->list = (hash_item **) malloc(length * sizeof(hash_item *));
        for (i = 0; i < length; i++) {
                self->list[i] = NULL;
        }
        self->length = length;
        self->hash_fun = hash_fun;
        self->key_cmp = key_cmp;
        self->item_copy = item_copy;


        self->hash_add = hash_add;
        self->hash_get = hash_get;
        return self;
}


hashing *hash_add(hashing * self, hash_item * item)
{
        int             h;
        hash_item      *p, *new_item;


        assert(self != NULL && item != NULL);


        h = self->hash_fun(item->key);
        assert(h < self->length);
        new_item = self->item_copy(item);
        new_item->next = NULL;
        p = self->list[h];
        if (p == NULL) {
                self->list[h] = new_item;
        } else {
                while (p->next != NULL) {
                        p = p->next;
                }
                p->next = new_item;
        }
        return self;
}


hash_item * hash_get(hashing * self, void *key)
{
        int             h;
        hash_item      *p;


        assert(self != NULL && key != NULL);


        h = self->hash_fun(key);
        assert(h < self->length);
        p = self->list[h];


        /* p!=NULL && key_cmp(p->key)  can't reserve */
        while (p != NULL && self->key_cmp(p->key, key)) {
                p = p->next;
        }
        if (p == NULL) {
                return NULL;
        }
        return p;


}


int str_hash_fun(void *key, int length)
{
        int             h, l, i;
        char           *str_key;


        assert(key != NULL && length > 1);


        str_key = (char *)key;
        l = strlen(str_key);
        h = 0;
        for (i = 0; i < l; i++) {
                h = (h + str_key[i]) % length;
        }
        return h;
}



hash_test.c


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hash.h"


#define LIST_LEN        47


int my_hash_fun(void *key)
{
        assert(key!=NULL);
        return str_hash_fun(key, LIST_LEN);
}


int   str_hash_key_cmp(void * key1, void * key2)
{
        assert(key1!=NULL && key2 != NULL);
        return strcmp(key1,key2);
}


hash_item *   my_item_copy(hash_item * x)
{
        hash_item * y;
        
        assert(x!=NULL);
        
        y = (hash_item *)malloc(sizeof(hash_item));
        assert(y != NULL);
        y->key = strdup((char*)x->key);
        y->data = (int *)malloc(sizeof(int));
        *((int *)(y->data)) = *((int *)(x->data));
        y->next = NULL;
        return y;
}
        
#define        STRS        10


char * my_strs[STRS] = {
                "hello", "go", "to", "pig", "dog", 
                "pear", "apple", "nut", "bananer", "orange"
        };


#define STRC        4


char *co_strs[STRC] = {
                "apple", "bananer", "pig", "go"
        };


void main(void)
{
        int i, k;
        hash_item M, *item_p;
        hashing *hashing_p;
        
        hashing_p = (hashing *)malloc(sizeof(hashing));
        assert(hashing_p!=NULL);
        
        init_hash(hashing_p, LIST_LEN, my_hash_fun, str_hash_key_cmp, my_item_copy);
        
        M.data = (int *)malloc(sizeof(int));
        for(item_p = &M, i = 0; i < STRS; i++)
        {
                fprintf(stdout, "%s is the No.  %d in list, No. %d item\n", my_strs[i], my_hash_fun(my_strs[i]), i);
                item_p->key = my_strs[i];
                *((int *)(item_p->data)) = i;
                hashing_p->hash_add(hashing_p, item_p);
        }
        fprintf(stdout, "\n init end\n\ncheck out date\n");
        for(i = 0; i<STRC; i++)
        {
                item_p = hashing_p->hash_get(hashing_p, co_strs[i]);
                assert(item_p!=NULL);
                k = *((int *)(item_p->data));
                fprintf(stdout, " %s is the No. %d item\n", co_strs[i], k );
                fprintf(stdout, "item_p =  %p\n",item_p);
        }
        
        return ;
}



Makefile


gcc hash.c hash_test.c -o hash_test



你可能感兴趣的:(c,list,pig,null,语言,fun)