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]) //
#define zc_arraylist_foreach(a_list, i, a_unit) \
for(i = , a_unit = a_list->array[]; (i < a_list->len) && (a_unit = a_list->array[i], ); i++) #endif
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(, 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 = ;
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=; 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 * , 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 -;
} 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 ;
} int zc_arraylist_set(zc_arraylist_t *a_list, int idx, void *data){
//idx start 0
if(idx > a_list->size - ){
if(zc_arraylist_expand_inner(a_list, idx)){
zc_error("expand_internal fail");
return -;
}
} 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 + ;
}
return ;
} 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 ;
}
if(a_list->len + > a_list->size){
if(zc_arraylist_expand_inner(a_list, )){
zc_error("expand_internal fail");
return -;
}
}
memmove(a_list->array + idx + , a_list->array + idx, (a_list->len - idx) * sizeof(void *)); a_list->array[idx] = data;
a_list->len++;
return ;
} int zc_arraylist_sortadd(zc_arraylist_t *a_list, zc_arraylist_cmp_fn cmp, void *data){
int i;
for(i = ; i < a_list->len; i++){
if((*cmp)(a_list->array[i], data) > ){
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);
}
}
用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(, strlen(p_str) + );
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);
}
测试结果