C语言实现 vector( 动态数组)

转载 2012年03月25日 12:25:25

//cvector.h

# ifndef __CVECTOR_H__  
# define __CVECTOR_H__  
  
# include <stdio.h>    
# include <stdlib.h>    
# include <string.h>    
  
# define MIN_LEN 256  
# define CVEFAILED  -1  
# define CVESUCCESS  0  
# define CVEPUSHBACK 1  
# define CVEPOPBACK  2  
# define CVEINSERT   3  
# define CVERM       4  
# define EXPANED_VAL 1  
# define REDUSED_VAL 2  
  
typedef void *citerator;  
typedef struct _cvector *cvector;  
  
# ifdef __cplusplus  
extern "C" {  
# endif  
  
    cvector   cvector_create   (const size_t size                           );  
    void      cvector_destroy  (const cvector cv                            );  
    size_t    cvector_length   (const cvector cv                            );  
    int       cvector_pushback (const cvector cv, void *memb                );  
    int       cvector_popback  (const cvector cv, void *memb                );  
    size_t    cvector_iter_at  (const cvector cv, citerator iter            );  
    int       cvector_iter_val (const cvector cv, citerator iter, void *memb);  
    citerator cvector_begin    (const cvector cv                            );  
    citerator cvector_end      (const cvector cv                            );  
    citerator cvector_next     (const cvector cv, citerator iter            );  
    int       cvector_val_at   (const cvector cv, size_t index, void *memb  );  
    int       cvector_insert   (const cvector cv, citerator iter, void *memb);  
    int       cvector_insert_at(const cvector cv, size_t index, void *memb  );  
    int       cvector_rm       (const cvector cv, citerator iter            );  
    int       cvector_rm_at    (const cvector cv, size_t index              );  
  
    /* for test  */  
    void      cv_info          (const cvector cv                            );  
    void      cv_print         (const cvector cv                            );  
  
# ifdef __cplusplus  
}  
# endif  
  
#endif


//cvector.c

#include "cvector.h"

#ifndef __gnu_linux__  
#define __func__ "unknown"  
#define inline __forceinline  
#endif  
  
//# define CWARNING_ITER(cv, iter, file, func, line) \  
//    do {\  
//    if ((cvector_begin(cv) > iter) || (cvector_end(cv) <= iter)) {\  
//    fprintf(stderr, "var(" #iter ") warng out of range, "\  
//    "at file:%s func:%s line:%d!!\n", file, func, line);\  
//    return CVEFAILED;\  
//    }\  
//    } while (0)  
  
struct _cvector  
{  
    void *cv_pdata;  
    size_t cv_len, cv_tot_len, cv_size;  
};  
  
cvector cvector_create(const size_t size)  
{  
    cvector cv = (cvector)malloc(sizeof (struct _cvector));  
  
    if (!cv) return NULL;  
  
    cv->cv_pdata = malloc(MIN_LEN * size);  
  
    if (!cv->cv_pdata)  
    {  
        free(cv);  
        return NULL;  
    }  
  
    cv->cv_size = size;  
    cv->cv_tot_len = MIN_LEN;  
    cv->cv_len = 0;  
  
    return cv;  
}    
  
void cvector_destroy(const cvector cv)    
{    
    free(cv->cv_pdata);    
    free(cv);    
    return;    
}    
  
size_t cvector_length(const cvector cv)    
{    
    return cv->cv_len;    
}    
  
int cvector_pushback(const cvector cv, void *memb)    
{    
    if (cv->cv_len >= cv->cv_tot_len)     
    {    
        void *pd_sav = cv->cv_pdata;    
        cv->cv_tot_len <<= EXPANED_VAL;    
        cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);    
  
        if (!cv->cv_pdata)     
        {    
            cv->cv_pdata = pd_sav;    
            cv->cv_tot_len >>= EXPANED_VAL;    
            return CVEPUSHBACK;    
        }    
    }    
  
    memcpy((char *)cv->cv_pdata + cv->cv_len * cv->cv_size, memb, cv->cv_size);    
    cv->cv_len++;    
  
    return CVESUCCESS;    
}    
  
int cvector_popback(const cvector cv, void *memb)    
{    
    if (cv->cv_len <= 0) return CVEPOPBACK;    
  
    cv->cv_len--;    
    memcpy(memb, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size, cv->cv_size);    
  
    if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))     
        && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL)))     
    {    
        void *pd_sav = cv->cv_pdata;    
        cv->cv_tot_len >>= EXPANED_VAL;    
        cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);    
  
        if (!cv->cv_pdata)     
        {    
            cv->cv_tot_len <<= EXPANED_VAL;    
            cv->cv_pdata = pd_sav;    
            return CVEPOPBACK;    
        }    
    }    
  
    return CVESUCCESS;    
}    
  
size_t cvector_iter_at(const cvector cv, citerator iter)    
{    
    //CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);    
    return ((char *)iter - (char *)cv->cv_pdata) / cv->cv_size;    
}    
  
int cvector_iter_val(const cvector cv, citerator iter, void *memb)    
{    
    //CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);    
    memcpy(memb, iter, cv->cv_size);    
    return 0;    
}    
  
citerator cvector_begin(const cvector cv)    
{    
    return cv->cv_pdata;    
}    
  
citerator cvector_end(const cvector cv)    
{    
    return (char *)cv->cv_pdata + (cv->cv_size * cv->cv_len);    
}    
  
static inline void cvmemove_foreward(const cvector cv, void *from, void *to)    
{    
    size_t size = cv->cv_size;    
    char *p;    
    for (p = (char *)to; p >= (char *)from; p -= size) memcpy(p + size, p, size);    
    return;    
}    
  
static inline void cvmemove_backward(const cvector cv, void *from, void *to)    
{    
    memcpy(from, (char *)from + cv->cv_size, (char *)to - (char *)from);    
    return;    
}    
  
int cvector_insert(const cvector cv, citerator iter, void *memb)    
{    
    //CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);    
  
    if (cv->cv_len >= cv->cv_tot_len)     
    {    
        void *pd_sav = cv->cv_pdata;    
        cv->cv_tot_len <<= EXPANED_VAL;    
        cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);    
  
        if (!cv->cv_pdata)     
        {    
            cv->cv_pdata = pd_sav;    
            cv->cv_tot_len >>= EXPANED_VAL;    
            return CVEINSERT;    
        }    
    }    
  
    cvmemove_foreward(cv, iter, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size);    
    memcpy(iter, memb, cv->cv_size);    
    cv->cv_len++;    
  
    return CVESUCCESS;    
}    
  
int cvector_insert_at(const cvector cv, size_t index, void *memb)    
{    
    citerator iter;    
  
    if (index >= cv->cv_tot_len)     
    {    
        cv->cv_len = index + 1;    
        while (cv->cv_len >= cv->cv_tot_len) cv->cv_tot_len <<= EXPANED_VAL;    
        cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);    
        iter = (char *)cv->cv_pdata + cv->cv_size * index;    
        memcpy(iter, memb, cv->cv_size);    
    }    
    else     
    {    
        iter = (char *)cv->cv_pdata + cv->cv_size * index;    
        cvector_insert(cv, iter, memb);    
    }    
  
    return 0;    
}    
  
citerator cvector_next(const cvector cv, citerator iter)    
{    
    return (char *)iter + cv->cv_size;    
}    
  
int cvector_val(const cvector cv, citerator iter, void *memb)    
{    
    memcpy(memb, iter, cv->cv_size);    
    return 0;    
}    
  
int cvector_val_at(const cvector cv, size_t index, void *memb)    
{    
    memcpy(memb, (char *)cv->cv_pdata + index * cv->cv_size, cv->cv_size);    
    return 0;    
}    
  
int cvector_rm(const cvector cv, citerator iter)    
{    
    citerator from;    
    citerator end;    
    //CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);    
    from = iter;    
    end = cvector_end(cv);    
    memcpy(from, (char *)from + cv->cv_size, (char *)end - (char *)from);    
    cv->cv_len--;    
  
    if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))    
        && (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL)))     
    {    
        void *pd_sav = cv->cv_pdata;    
        cv->cv_tot_len >>= EXPANED_VAL;    
        cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);    
  
        if (!cv->cv_pdata)     
        {    
            cv->cv_tot_len <<= EXPANED_VAL;    
            cv->cv_pdata = pd_sav;    
            return CVERM;    
        }    
    }    
  
    return CVESUCCESS;    
}    
  
int cvector_rm_at(const cvector cv, size_t index)    
{    
    citerator iter;    
    iter = (char *)cv->cv_pdata + cv->cv_size * index;    
    //CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);    
    return cvector_rm(cv, iter);    
}    
  
void cv_info(const cvector cv)    
{    
    printf("\n\ntot :%s : %d\n", __func__, cv->cv_tot_len);    
    printf("len :%s : %d\n",     __func__, cv->cv_len);    
    printf("size:%s : %d\n\n",   __func__, cv->cv_size);    
    return;    
}    
  
void cv_print(const cvector cv)    
{    
    int num;    
    citerator iter;    
  
    if (cvector_length(cv) == 0)    
        fprintf(stderr, "file:%s func:%s line:%d error, null length cvector!!\n", __FILE__, __func__, __LINE__);    
  
    for (iter = cvector_begin(cv);     
        iter != cvector_end(cv);    
        iter = cvector_next(cv, iter))     
    {    
        cvector_iter_val(cv, iter, &num);    
        printf("var:%d at:%d\n", num, cvector_iter_at(cv, iter));    
    }    
  
    return;    
} 

//main.cpp

typedef struct point
{
	int a;
	int b;
}DPOINT;

int main()
{
	cvector cv = cvector_create(sizeof(POINT)); 
	DPOINT pt;
	for(int i = 0; i < 10; i++)
	{
		pt.a = i;
		pt.b = i + 1;
		cvector_pushback(cv, &pt);
	}
	int a;
	for(int i = 0; i < 10; i++)
	{
		cvector_val_at(cv, i, &pt);
		printf("%d, %d\n", pt.a, pt.b);
	}


	cvector_destroy(cv); 
	return 0;
}




                    

动态数组的C语言实现

  • 2010年09月14日 16:34
  • 2KB
  • 下载

c语言实现一个简单的通用动态数组

背景 最近在看《系统程序员成长计划》,里面有个任务是实现一个动态数组,所以我用以前学过的知识实现了一个通用的动态数组,不过暂时只能存放int,char,double,字符串的还没实现。 设计与实现 一...

C语言中动态数组的实现

近来编写几个程序,很多都用到了数组。但是对于数组的大小却是没有固定的,也就是说可以更改数组大小,其大小是可以变化的。并不像初学时的那样,告诉你一个范围,你就必须取最大值以满足要求。那样可能就会浪费很多...

C语言堆栈实现( 动态数组 )

/* * stack.h * * Created on: 2011-10-7 * Author: Admin */ #ifndef STACK_H_ #define STACK...

《C语言接口与实现》实验——动态数组(Array_T)

实验程序是用vc6编译,一定注意文件扩展名为c,不是cpp,下载前面几个测试程序(链表、表、原子中有下载链接)中直接将下面源程序覆盖1.c的内容即可! 源程序如下: #in...

C语言实现使用动态数组实现循环队列

我在上一篇博客《C语言实现使用静态数组实现循环队列》中实现了使用静态数组来模拟队列的操作。由于数组的大小已经被指定,无法动态的扩展。所以在这篇博客中,我换成动态数组来实现。动态数组可以不断开辟内存空间...

C语言动态数组原理及实现

近来编写几个程序,很多都用到了数组。但是对于数组的大小却是没有固定的,也就是说可以更改数组大小,其大小是可以变化的。并不像初学时的那样,告诉你一个范围,你就必须取最大值以满足要求。那样可能就会浪费很多...

线性表之顺序存储结构(C语言动态数组实现)

线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) ...
  • xyang81
  • xyang81
  • 2014年05月16日 00:17
  • 2900

C语言实现动态数组(以面向对象的编程风格)

/******************************************************************************* ** 程序名称:动态数组 ** 程...

C语言实现使用动态数组来构造栈结构

我在面前一篇博客《C语言实现使用静态数组来构造栈结构》中使用了静态数组来模拟栈的操作。静态数组的大小是在代码中写死的,是存储在用户栈上面的,使用起来不灵活。在这篇博客中我会使用动态数组来构造,此时使用...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言实现 vector( 动态数组)
举报原因:
原因补充:

(最多只允许输入30个字)