• C 工具库4:变长数组(vector)


    vector.h

    #ifndef _VECTOR_H
    #define _VECTOR_H

    struct vector;


    struct vector *vector_create(unsigned int val_size,unsigned int reserve_size);
    struct vector *vector_copy_create(struct vector*);
    void vector_copy(struct vector*,struct vector*);

    void vector_reserve(struct vector*,unsigned int);

    void vector_destroy(struct vector**);

    unsigned int vector_size(struct vector*);
    unsigned int vector_capability(struct vector*);
    void vector_push_back(struct vector*,void*);

    #ifndef VECTOR_PUSH_BACK
    #define VECTOR_PUSH_BACK(TYPE,VECTOR,VAL)\
    {TYPE val = VAL;vector_push_back(VECTOR,&val);}
    #endif

    void vector_get(struct vector*,unsigned int,void*);
    void vector_set(struct vector*,unsigned int,void*);

    void* vector_to_array(struct vector*);

    #ifndef VECTOR_TO_ARRAY
    #define VECTOR_TO_ARRAY(TYPE,VECTOR)\
    ({ TYPE *__result;\
    do __result = (TYPE*)vector_to_array(VECTOR);\
    while(0);\
    __result;})
    #endif

    #ifndef VECTOR_GET
    #define VECTOR_GET(TYPE,VECTOR,I)\
    ({ TYPE __result;\
    do vector_get(VECTOR,I,&__result);\
    while(0);\
    __result;})
    #endif

    #ifndef VECTOR_SET
    #define VECTOR_SET(TYPE,VECTOR,I,VAL)\
    {TYPE val=VAL;vector_set(VECTOR,I,&val);}
    #endif




    #endif

    vector.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "vector.h"

    struct vector
    {
    unsigned int size;
    unsigned int capability;
    unsigned int val_size;
    char *buf;
    };

    struct vector *vector_create(unsigned int val_size,unsigned int reserve_size)
    {
    struct vector *v = malloc(sizeof(*v));
    if(v)
    {
    if(reserve_size)
    {
    v->buf = malloc(val_size*reserve_size);
    if(!v->buf)
    {
    free(v);
    return 0;
    }
    }
    else
    v->buf = 0;
    v->size = v->capability = reserve_size;
    v->val_size = val_size;

    }
    return v;
    }

    struct vector *vector_copy_create(struct vector *v)
    {
    assert(v);
    if(!v->buf)
    return vector_create(v->val_size,0);
    struct vector *ret = malloc(sizeof(*v));
    if(ret)
    {
    ret->buf = malloc(v->capability*v->val_size);
    if(!ret->buf)
    {
    free(ret);
    ret = 0;
    }
    else
    {
    ret->val_size = v->val_size;
    ret->size = v->size;
    ret->capability = v->capability;
    memcpy(ret->buf,v->buf,v->val_size*v->size);
    }
    }
    return ret;
    }

    void vector_copy(struct vector *v,struct vector *other)
    {
    assert(v);
    assert(other);
    if(!other->buf)
    return;
    if(v->val_size == other->val_size)
    {
    if(v->capability < other->capability)
    {
    unsigned int new_size = other->capability*other->val_size;
    char *buf = realloc(v->buf,new_size);
    if(!buf)
    buf = malloc(new_size);
    if(!buf)
    return;
    if(buf != v->buf)
    {
    free(v->buf);
    v->buf = buf;
    }
    v->capability = other->capability;
    }
    memcpy(v->buf,other->buf,other->size*other->val_size);
    v->size = other->size;
    }
    }

    void vector_destroy(struct vector **v)
    {
    assert(v);
    assert(*v);
    if((*v)->buf)
    free((*v)->buf);
    free(*v);
    *v = 0;
    }

    void vector_reserve(struct vector *v,unsigned int reserve_size)
    {
    assert(v);
    if(v->capability > reserve_size)
    {
    //缩小容量的情况,不重新分配内存,仅仅将capality的值减小
    v->capability = reserve_size;
    if(v->size > reserve_size)
    v->size = reserve_size;
    }
    else
    {
    //需要扩大内存
    unsigned int new_size = v->val_size * reserve_size;
    char *buf = realloc(v->buf,new_size);
    if(!buf)
    buf = malloc(new_size);
    if(!buf)
    return;

    v->capability = reserve_size;
    if(buf != v->buf)
    {
    memcpy(buf,v->buf,v->val_size*v->size);
    free(v->buf);
    v->buf = buf;
    }
    }
    }

    inline void *vector_get_addr_by_idx(struct vector *v,unsigned int idx)
    {
    return (void*)&v->buf[v->val_size*idx];
    }

    inline unsigned int vector_size(struct vector *v)
    {
    assert(v);
    return v->size;
    }

    inline unsigned int vector_capability(struct vector *v)
    {
    assert(v);
    return v->capability;
    }

    inline void* vector_to_array(struct vector *v)
    {
    assert(v);
    return v->buf;
    }

    void vector_push_back(struct vector *v,void *val)
    {
    assert(v);
    if(v->size == v->capability)
    {
    //扩展空间
    unsigned int new_size = v->capability > 0 ? 2*(v->capability) : 32;
    unsigned int capability = new_size;
    new_size *= v->val_size;
    char *buf = realloc(v->buf,new_size);
    if(!buf)
    buf = malloc(new_size);
    if(!buf)
    return;
    if(buf != v->buf)
    {
    memcpy(buf,v->buf,v->val_size*v->capability);
    free(v->buf);
    v->buf = buf;
    }
    v->capability = capability;
    }
    memcpy(vector_get_addr_by_idx(v,v->size),val,v->val_size);
    ++v->size;
    }


    void vector_get(struct vector *v,unsigned int idx,void *val)
    {
    assert(v);
    if(v->buf && idx < v->capability)
    {
    memcpy(val,vector_get_addr_by_idx(v,idx),v->val_size);
    }
    }

    void vector_set(struct vector *v,unsigned int idx,void *val)
    {
    assert(v);
    if(v->buf && idx < v->capability)
    {
    memcpy(vector_get_addr_by_idx(v,idx),val,v->val_size);
    }
    }

    test.c

    #include <stdio.h>
    #include "vector.h"

    int main()
    {
    struct vector *v = vector_create(sizeof(int),64);
    int i;
    for(i = 0; i < 64; ++i)
    VECTOR_SET(int,v,i,i);

    vector_reserve(v,32);
    VECTOR_PUSH_BACK(int,v,33);
    VECTOR_PUSH_BACK(int,v,34);

    //VECTOR_PUSH_BACK(int,v,i);






    //struct vector *other = vector_copy_create(v);
    //vector_copy(other,v);
    //printf("h");

    int *a = VECTOR_TO_ARRAY(int,v);
    for(i = 0; i < vector_size(v); ++i)
    printf("%d\n",a[i]);

    printf("capability :%d\n",vector_capability(v));
    return 0;

    }





  • 相关阅读:
    【ACM】nyoj_139_我排第几个_201308062046
    【ACM】poj_2356_Find a multiple_201308061947
    【ACM】hdu_zs2_1007_Problem G _201308031028
    【ACM】hdu_zs2_1006_Problem F_201308031058
    【ACM】hdu_zs2_1005_Problem E _201308030747
    【ACM】hdu_zs2_1004_Problem D _201308030856
    【葡萄城报表案例分享】项目施工进度报告 – 树形报表
    【葡萄城报表案例分享】电力设备生产数据的多层分组统计报表实现
    葡萄城报表之多维透视表 – 矩表实现商品销售对比统计
    葡萄城报表之矩表 – 现代数据分析中必不可少的报表工具
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2429614.html
Copyright © 2020-2023  润新知