读书人

花了一天时间用c写了一个类似java中的

发布时间: 2012-05-15 14:35:29 作者: rapoo

花了一天时间用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_INCLUDED




arraylist.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);} 



[解决办法]
探讨

当元素的类型是字符串或int时,在indexOf或remove时,判断麻烦,需要

if(items->E == E_STRING)
{
}
else if(items->E == E_INT)
{
}

这个地方实现的不太好,不知有没有什么改进的好办法。

[解决办法]
多种数据类型用一个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;        }    }}
[解决办法]
探讨



引用:
不知道我这个是不是泛型,看起来比你的要简洁一点.

C/C++ code


list.h
/*
*/
#ifndef __LIST_H__
#define __LIST_H__

typedef void *Element;

typedef struct node{
Element e;
struct node ……

读书人网 >C语言

热点推荐