bai_jimmy

导航

zlog学习笔记(zc_arraylist)

zc_arraylist.h

/**
 * 实现类似列表的功能
 * 
 */

#ifndef __zc_arraylist_h
#define __zc_arraylist_h

#define ARRAY_LIST_DEFAULT_SIZE 32

//删除、比较两个函数类型声明
typedef void (*zc_arraylist_del_fn) (void *data);
typedef int (*zc_arraylist_cmp_fn) (void *data1, void *data2);

typedef struct{
        void **array; //指针的指针
        int len;
        int size;
        zc_arraylist_del_fn del;
} zc_arraylist_t;

zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del);
void zc_arraylist_del(zc_arraylist_t *a_list);

int zc_arraylist_set(zc_arraylist_t *a_list, int i, void *data);
int zc_arraylist_add(zc_arraylist_t *a_list, void *data);
int zc_arraylist_sortadd(zc_arraylist_t *a_list, zc_arraylist_cmp_fn cmp, void *data);

#define zc_arraylist_len(a_list) (a_list->len)

//i从0开始
#define zc_arraylist_get(a_list, i) \
        ((i >= a_list->len) ? NULL : a_list->array[i])

//100
#define zc_arraylist_foreach(a_list, i, a_unit) \
        for(i = 0, a_unit = a_list->array[0]; (i < a_list->len) && (a_unit = a_list->array[i], 1); i++)

#endif
View Code

zc_arraylist.h

#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "zc_defs.h"

zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del){
        zc_arraylist_t *a_list;

        a_list = (zc_arraylist_t *)calloc(1, sizeof(zc_arraylist_t));
        if(!a_list){
                zc_error("calloc fail, errno[%d]", errno);
                return NULL;
        }

        a_list->size = ARRAY_LIST_DEFAULT_SIZE;
        a_list->len = 0;
        a_list->del = del;      //this could be null
        a_list->array = (void **)calloc(a_list->size, sizeof(void *));
        if(!a_list->array){
                zc_error("calloc fail, errno[%d]", errno);
                free(a_list);
                return NULL;
        }

        return a_list;
}

void zc_arraylist_del(zc_arraylist_t *a_list){
        int i;
        if(!a_list){
                return;
        }
        if(a_list->del){
                for(i=0; i<a_list->len; i++){
                        //notice NULL
                        if(a_list->array[i]){
                                a_list->del(a_list->array[i]);
                        }
                }
        }
        if(a_list->array){
                free(a_list->array);
        }
        free(a_list);
        return;
}

/**
 * static->function, external->internal
 */
static int zc_arraylist_expand_inner(zc_arraylist_t *a_list, int max){
        void **tmp;
        int new_size;
        int diff_size;

        new_size = zc_max(a_list->size * 2, max);
        tmp = (void **)realloc(a_list->array, new_size * sizeof(void *));
        if(!tmp){
                zc_error("realloc fail, errno[%d]", errno);
                free(a_list->array); //notice no question?
                return -1;
        }

        a_list->array = tmp;
        diff_size = new_size - a_list->size;
        if(diff_size){
                memset(a_list->array + a_list->size, 0x00, diff_size * sizeof(void *));
        }
        a_list->size = new_size;
        return 0;
}

int zc_arraylist_set(zc_arraylist_t *a_list, int idx, void *data){
        //idx start 0
        if(idx > a_list->size - 1){
                if(zc_arraylist_expand_inner(a_list, idx)){
                        zc_error("expand_internal fail");
                        return -1;
                }
        }

        if(a_list->array[idx] && a_list->del){
                a_list->del(a_list->array[idx]);
        }

        a_list->array[idx] = data;
        if(a_list->len <= idx){
                a_list->len = idx + 1;
        }
        return 0;
}

int zc_arraylist_add(zc_arraylist_t *a_list, void *data){
        return zc_arraylist_set(a_list, a_list->len, data);
}

//assume idx < len
static int zc_arraylist_insert_inner(zc_arraylist_t *a_list, int idx, void *data){
        if(a_list->array[idx] == NULL){
                a_list->array[idx] = data;
                return 0;
        }
        if(a_list->len + 1 > a_list->size){
                if(zc_arraylist_expand_inner(a_list, 0)){
                        zc_error("expand_internal fail");
                        return -1;
                }
        }
        memmove(a_list->array + idx + 1, a_list->array + idx, (a_list->len - idx) * sizeof(void *));

        a_list->array[idx] = data;
        a_list->len++;
        return 0;
}

int zc_arraylist_sortadd(zc_arraylist_t *a_list, zc_arraylist_cmp_fn cmp, void *data){
        int i;
        for(i = 0; i < a_list->len; i++){
                if((*cmp)(a_list->array[i], data) > 0){
                        break;
                }
        }

        if(i == a_list->len){
                return zc_arraylist_add(a_list, data);
        }else{
                //i < a_list->len
                return zc_arraylist_insert_inner(a_list, i, data);
        }
}
View Code

 

用zc_arraylist实现一个字符串列表功能,测试zc_arraylist

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "zc_defs.h"


char *char_new(char *p_str){
        char *p = (char *)calloc(1, strlen(p_str) + 1);
        if(!p){
                return NULL;
        }
        strncpy(p, p_str, strlen(p_str));
        return p;
}

void char_del(void *p_str){
        if(!p_str){
                return;
        }
        free(p_str);
}

int main(){
        zc_arraylist_t *char_list = zc_arraylist_new(char_del);
        zc_arraylist_add(char_list,char_new("www.baidu.com"));
        zc_arraylist_add(char_list,char_new("www.qq.com"));
        zc_arraylist_add(char_list,char_new("www.ifeng.com"));

        int i;
        char *char_item;
        zc_arraylist_foreach(char_list, i, char_item){
                printf("%s\n", char_item);
        }

        zc_arraylist_del(char_list);
}
View Code

 

测试结果

posted on 2016-04-09 09:53  bai_jimmy  阅读(219)  评论(0编辑  收藏  举报