花了一天时间用c写了一个类似java中的ArrayList<E>,接受大家的检阅
在java中像ArrayList,Vector,HashMap都是现成的,在java.util包中,用的时候直接import java.util.*就行了。
在c语言中,由于我学c时间不长(以前学的是java,去年网购了一本《C程序设计语言》(第2版-新版),在家里有空就翻开看看,大概花了一二个月把书看完了),不知道ArrayList到哪个库里找,刚好今天有空,也为了练习一下c,我就参照着jdk中的ArrayList源码,写了一个c版的ArrayList,意外的是,我发现我写的这个ArrayList多少有点泛型的特征<E>。
直接上代码,接受大家的检阅(欢迎大家指出问题):
arraylist.h
- C/C++ code
#ifndef ARRAYLIST_H_INCLUDED#define ARRAYLIST_H_INCLUDEDtypedef struct arraylist{ int E; //类似java中的泛型 void **pItemList; //指向指针的指针,由于要实现类似java中的<E>泛型效果,这里使用 void 类型指针 int capacity; //当前容量 int factor; //扩展因子,当空间不够用时 int size; //当前元素的数量} *ArrayList;enum ArrayList_E{E_STRING,E_INT}; //枚举类型ArrayList arraylist_init(int E); //初始化void arraylist_add(ArrayList items,void *pItem); //将指定的元素追加到此列表的尾部。int arraylist_insert(ArrayList items,int index,void *pItem); //将指定的元素插入此列表中的指定位置int arraylist_indexOf(ArrayList items,void * pItem); //搜索给定参数第一次出现的位置int arraylist_lastIndexOf(ArrayList items, void *pItem); //返回指定的对象在列表中最后一次出现的位置索引int arraylist_remove(ArrayList items, void *pItem); //从此列表中移除指定元素的单个实例(如果存在)void *arraylist_removeIndex(ArrayList items,int index); //移除此列表中指定位置上的元素void arraylist_set(ArrayList items,int index,void *pItem); //用指定的元素替代此列表中指定位置上的元素void *arraylist_get(ArrayList items,int index); //返回此列表中指定位置上的元素void arraylist_clear(); //移除此列表中的所有元素。#endif // ARRAYLIST_H_INCLUDEDarraylist.c
- C/C++ code
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "arraylist.h"//初始化ArrayList arraylist_init(int E){ ArrayList items = malloc(sizeof(struct arraylist)); items->E = E; items->capacity = 10; items->factor = 3; items->size = 0; items->pItemList = malloc(sizeof(void *) * items->capacity); return items;}//重置容量,当可用容量不够用时,自动扩大3个//static 作用类似java中的privatestatic void arraylist_resize_capacity(ArrayList items){ if(items->size == items->capacity) { //printf("空间用完了,扩大空间 -> %d\n",items->size); items->capacity = items->size + items->factor; //扩大容量 void **newItemList = malloc(sizeof(void *) * items->capacity); //将原来的指针指向的内容复制到新的空间中 memcpy(newItemList,items->pItemList,sizeof(void *) * items->size); free(items->pItemList); //释放原来指向的空间 items->pItemList = newItemList; //指向新空间 }}//将指定的元素追加到此列表的尾部。void arraylist_add(ArrayList items,void *pItem){ arraylist_resize_capacity(items); *(items->pItemList + items->size) = pItem; items->size++; //size + 1}//将指定的元素插入此列表中的指定位置,成功返回1,失败返回0int arraylist_insert(ArrayList items,int index,void *pItem){ if(index <= items->size) { arraylist_resize_capacity(items); void **pItemList = items->pItemList; //移动指针指向的地址,即将数组中的元素从index开始向后移动一位 int i; for(i = items->size; i>index; i--) { *(pItemList+i) = *(pItemList+i-1); } *(pItemList+index) = pItem; //将新的元素插入到这个位置 items->size++; //size + 1 return 1; } else { return 0; }}//搜索给定参数第一次出现的位置,找到返回index,找不到返回-1int arraylist_indexOf(ArrayList items, void *pItem){ int i=0; int size = items->size; void **pItemList = items->pItemList; if(items->E == E_STRING) { for(; i<size; i++) { if(*pItemList == pItem || strcmp(*pItemList,pItem) == 0) { return i; } pItemList++; } } else if(items->E == E_INT) { //printf("------- %d,%d\n",*(int *)pItemList,*(int *)pItem); for(; i<size; i++) { //如果指针的值或指针指向的最终变量的值是一样的 if(*pItemList == pItem || *(int *)pItemList == *(int *)pItem) { return i; } pItemList++; } } else { for(; i<size; i++) { //如果指针的值或指针指向的最终变量的值是一样的 if(*pItemList == pItem) { return i; } pItemList++; } } return -1;}//返回指定的对象在列表中最后一次出现的位置索引,找到返回index,找不到返回-1int arraylist_lastIndexOf(ArrayList items, void *pItem){ int i; int size = items->size; void **pItemList = items->pItemList; if(items->E == E_STRING) { for(i=size-1; i>-1; i--) { if(*(pItemList+i) == pItem || strcmp(*(pItemList+i),pItem) == 0) { return i; } } } else if(items->E == E_INT) { //printf("------- %d,%d\n",*(int *)pItemList,*(int *)pItem); for(i=size-1; i>-1; i--) { if(*(pItemList+i) == pItem || *(int *)(pItemList + i) == *(int *)pItem) { return i; } } } else { for(i=size-1; i>-1; i--) { if(*(pItemList+i) == pItem) { return i; } } } return -1;}//从此列表中移除指定元素的单个实例,如果存在就返回1,反之返回0int arraylist_remove(ArrayList items, void *pItem){ int i=0; int size = items->size; void **pItemList = items->pItemList; for(; i<size; i++) { if(items->E == E_STRING) { if(*(pItemList+i) == pItem || strcmp(*(pItemList+i),pItem) == 0) { //移动指针指向的地址,即将数组中的元素从index开始向前移动一位 int m; for(m = i; m<size-1; m++) { *(pItemList + m) = *(pItemList + m + 1); } *(pItemList + size - 1) = NULL; //将新的元素插入到这个位置 items->size--; //size - 1 return i; } } else if(items->E == E_INT) { if(*(pItemList+i) == pItem || *(int *)(pItemList + i) == *(int *)pItem) { //移动指针指向的地址,即将数组中的元素从index开始向前移动一位 int m; for(m = i; m<size-1; m++) { *(pItemList + m) = *(pItemList + m + 1); } *(pItemList + size - 1) = NULL; //将新的元素插入到这个位置 items->size--; //size - 1 return i; } } else { if(*(pItemList+i) == pItem) { //移动指针指向的地址,即将数组中的元素从index开始向前移动一位 int m; for(m = i; m<size-1; m++) { *(pItemList + m) = *(pItemList + m + 1); } *(pItemList + size - 1) = NULL; //将新的元素插入到这个位置 items->size--; //size - 1 return i; } } } return -1;}//移除此列表中指定位置上的元素,返回被移除的元素void *arraylist_removeIndex(ArrayList items,int index){ int size = items->size; if(index >= size || index < 0) { return NULL; } else { void **pItemList = items->pItemList; void *pItem = *(pItemList + index); //取得index位置的指针的值 //移动指针指向的地址,即将数组中的元素从index开始向前移动一位 int m; for(m = index; m<size-1; m++) { *(pItemList + m) = *(pItemList + m + 1); } *(pItemList + size - 1) = NULL; //将尾部的指针的值设置为NULL items->size--; //size - 1 return pItem; }}//用指定的元素替代此列表中指定位置上的元素,返回: 以前位于该指定位置上的元素void arraylist_set(ArrayList items,int index,void *pItem){ int size = items->size; if(index <= size && size > 0) { *(items->pItemList + index) = pItem; }}//返回此列表中指定位置上的元素void *arraylist_get(ArrayList items,int index){ int size = items->size; if(index >= 0 && index <= size && size > 0) { return *(items->pItemList+index); } else { return NULL; }}//移除此列表中的所有元素void arraylist_clear(ArrayList items){ free(items->pItemList); //释放内存 //重新初始化 items->capacity = 10; items->factor = 3; items->size = 0; items->pItemList = malloc(sizeof(void *) * items->capacity);}
[解决办法]
[解决办法]
多种数据类型用一个ArrayList控制显的有点乱
[解决办法]
不知道我这个是不是泛型,看起来比你的要简洁一点.
- C/C++ code
list.h/* */#ifndef __LIST_H__#define __LIST_H__ typedef void *Element; typedef struct node{ Element e; struct node * next;}*Node;//无序列表typedef struct list *List;struct list{ Node nodes; void (*add)(List this,Element); //添加元素到列表头. void (*addLast)(List this,Element); //添加元素到列表尾部. void (*remove)(List this); //删除列表头部元素. void (*removeLast)(List this); //删除链表尾部元素. Node (*first)(List this); //获取列表第一个节点. Node (*last)(List this); //获取列表最后一节点. void (*removeNode)(Node); //节点资源释放函数 void (*forEach)(List this,void(*)(Node)); //遍历节点}; extern List newList(void (*remove)(Node)); //new一个列表对象extern void delList(List this); //删除一个列表对象#endif list.c/* * 程序遵循的规则是:函数对传递下来的参数做合法性监测,不合法的参数,程序直接停止 * 工作.错误处理交给调用者处理. */#include "list.h"#include <malloc.h>#include <stdlib.h> //添加一个元素到列表static void _add(List this,Element e){ if(NULL == this) exit(1); Node node = NULL; node = malloc(sizeof(*node)); if(NULL == node) exit(1); node->e = e; node->next = this->nodes; this->nodes = node;} //添加一个元素到列表尾static void _addLast(List this,Element e){ if(NULL == this) exit(1); Node node; Node p = this->nodes; node = malloc(sizeof(*node)); if(NULL == node) exit(1); node->e = e; node->next =NULL; if(NULL == this->nodes) this->nodes = node; else{ while(NULL != p->next) p = p->next; p->next = node; }} //删除列表头部元素static void _remove(List this){ Node node; if(NULL == this) exit(1); if(NULL != this->nodes){ node = this->nodes; this->nodes = node->next; this->removeNode(node); }} //删除列表尾部元素static void _removeLast(List this){ Node node,p; if(NULL == this) exit(1); p = this->nodes; node = this->nodes; if(NULL != p){ while(NULL != node->next){ p = node; node = node->next; } p->next = NULL; this->removeNode(node); } } //获取列表第一个节点static Node _first(List this){ if(NULL == this) exit(1);} //获取列表最后一个节点static Node _last(List this){ if(NULL == this) exit(1);} //遍历节点static void _forEach(List this,void(*backfunc)(Node)){ Node node = NULL; if(NULL == this) return; node = this->nodes; while(NULL != node){ backfunc(node); node = node->next; }} //new一个List对象extern List newList(void (*_removeNode)(Node node)){ List L; L = malloc(sizeof(*L)); if(NULL == L) return NULL; L->nodes = NULL; L->add = _add; L->addLast = _addLast; L->remove = _remove; L->removeLast = _removeLast; L->last = _last; L->first = _first; L->removeNode = _removeNode; L->forEach = _forEach; return L;}//删除对象extern void deList(List this){ if(NULL != this){ Node node; Node p = this->nodes; while(p != NULL){ node = p->next; removeNode(p); p = node; } }}
[解决办法]