使用C语言实现vector动态数组的实例分享
下面是做项目时实现的一个动态数组,先后加入了好几个之后的项目,下面晒下代码。
头文件:
#ifndef__CVECTOR_H__ #define__CVECTOR_H__ #defineMIN_LEN256 #defineCVEFAILED-1 #defineCVESUCCESS0 #defineCVEPUSHBACK1 #defineCVEPOPBACK2 #defineCVEINSERT3 #defineCVERM4 #defineEXPANED_VAL1 #defineREDUSED_VAL2 typedefvoid*citerator; typedefstruct_cvector*cvector; #ifdef_cplusplus #defineEXTERN_extern"C" #else #defineEXTERN_extern #endif EXTERN_cvectorcvector_create(constsize_tsize); EXTERN_voidcvector_destroy(constcvectorcv); EXTERN_size_tcvector_length(constcvectorcv); EXTERN_intcvector_pushback(constcvectorcv,void*memb); EXTERN_intcvector_popback(constcvectorcv,void*memb); EXTERN_size_tcvector_iter_at(constcvectorcv,citeratoriter); EXTERN_intcvector_iter_val(constcvectorcv,citeratoriter,void*memb); EXTERN_citeratorcvector_begin(constcvectorcv); EXTERN_citeratorcvector_end(constcvectorcv); EXTERN_citeratorcvector_next(constcvectorcv,citeratoriter); EXTERN_intcvector_val_at(constcvectorcv,size_tindex,void*memb); EXTERN_intcvector_insert(constcvectorcv,citeratoriter,void*memb); EXTERN_intcvector_insert_at(constcvectorcv,size_tindex,void*memb); EXTERN_intcvector_rm(constcvectorcv,citeratoriter); EXTERN_intcvector_rm_at(constcvectorcv,size_tindex); /*fortest*/ EXTERN_voidcv_info(constcvectorcv); EXTERN_voidcv_print(constcvectorcv); #endif/*EOFfilecvector.h*/
C文件:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#defineMIN_LEN256
#defineCVEFAILED-1
#defineCVESUCCESS0
#defineCVEPUSHBACK1
#defineCVEPOPBACK2
#defineCVEINSERT3
#defineCVERM4
#defineEXPANED_VAL1
#defineREDUSED_VAL2
typedefvoid*citerator;
typedefstruct_cvector
{
void*cv_pdata;
size_tcv_len,cv_tot_len,cv_size;
}*cvector;
#defineCWARNING_ITER(cv,iter,file,func,line)\
do{\
if((cvector_begin(cv)>iter)||(cvector_end(cv)<=iter)){\
fprintf(stderr,"var("#iter")warngoutofrange,"\
"atfile:%sfunc:%sline:%d!!/n",file,func,line);\
returnCVEFAILED;\
}\
}while(0)
#ifdef_cplusplus
#defineEXTERN_extern"C"
#else
#defineEXTERN_extern
#endif
EXTERN_cvectorcvector_create(constsize_tsize);
EXTERN_voidcvector_destroy(constcvectorcv);
EXTERN_size_tcvector_length(constcvectorcv);
EXTERN_intcvector_pushback(constcvectorcv,void*memb);
EXTERN_intcvector_popback(constcvectorcv,void*memb);
EXTERN_size_tcvector_iter_at(constcvectorcv,citeratoriter);
EXTERN_intcvector_iter_val(constcvectorcv,citeratoriter,void*memb);
EXTERN_citeratorcvector_begin(constcvectorcv);
EXTERN_citeratorcvector_end(constcvectorcv);
EXTERN_citeratorcvector_next(constcvectorcv,citeratoriter);
EXTERN_intcvector_val_at(constcvectorcv,size_tindex,void*memb);
EXTERN_intcvector_insert(constcvectorcv,citeratoriter,void*memb);
EXTERN_intcvector_insert_at(constcvectorcv,size_tindex,void*memb);
EXTERN_intcvector_rm(constcvectorcv,citeratoriter);
EXTERN_intcvector_rm_at(constcvectorcv,size_tindex);
/*fortest*/
EXTERN_voidcv_info(constcvectorcv);
EXTERN_voidcv_print(constcvectorcv);
cvectorcvector_create(constsize_tsize)
{
cvectorcv=(cvector)malloc(sizeof(struct_cvector));
if(!cv)returnNULL;
cv->cv_pdata=malloc(MIN_LEN*size);
if(!cv->cv_pdata)
{
free(cv);
returnNULL;
}
cv->cv_size=size;
cv->cv_tot_len=MIN_LEN;
cv->cv_len=0;
returncv;
}
voidcvector_destroy(constcvectorcv)
{
free(cv->cv_pdata);
free(cv);
return;
}
size_tcvector_length(constcvectorcv)
{
returncv->cv_len;
}
intcvector_pushback(constcvectorcv,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;
returnCVEPUSHBACK;
}
}
memcpy(cv->cv_pdata+cv->cv_len*cv->cv_size,memb,cv->cv_size);
cv->cv_len++;
returnCVESUCCESS;
}
intcvector_popback(constcvectorcv,void*memb)
{
if(cv->cv_len<=0)returnCVEPOPBACK;
cv->cv_len--;
memcpy(memb,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;
returnCVEPOPBACK;
}
}
returnCVESUCCESS;
}
size_tcvector_iter_at(constcvectorcv,citeratoriter)
{
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
return(iter-cv->cv_pdata)/cv->cv_size;
}
intcvector_iter_val(constcvectorcv,citeratoriter,void*memb)
{
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
memcpy(memb,iter,cv->cv_size);
return0;
}
citeratorcvector_begin(constcvectorcv)
{
returncv->cv_pdata;
}
citeratorcvector_end(constcvectorcv)
{
returncv->cv_pdata+(cv->cv_size*cv->cv_len);
}
staticinlinevoidcvmemove_foreward(constcvectorcv,void*from,void*to)
{
size_tsize=cv->cv_size;
void*p;
for(p=to;p>=from;p-=size)memcpy(p+size,p,size);
return;
}
staticinlinevoidcvmemove_backward(constcvectorcv,void*from,void*to)
{
memcpy(from,from+cv->cv_size,to-from);
return;
}
intcvector_insert(constcvectorcv,citeratoriter,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;
returnCVEINSERT;
}
}
cvmemove_foreward(cv,iter,cv->cv_pdata+cv->cv_len*cv->cv_size);
memcpy(iter,memb,cv->cv_size);
cv->cv_len++;
returnCVESUCCESS;
}
intcvector_insert_at(constcvectorcv,size_tindex,void*memb)
{
citeratoriter;
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=cv->cv_pdata+cv->cv_size*index;
memcpy(iter,memb,cv->cv_size);
}
else
{
iter=cv->cv_pdata+cv->cv_size*index;
cvector_insert(cv,iter,memb);
}
return0;
}
citeratorcvector_next(constcvectorcv,citeratoriter)
{
returniter+cv->cv_size;
}
intcvector_val(constcvectorcv,citeratoriter,void*memb)
{
memcpy(memb,iter,cv->cv_size);
return0;
}
intcvector_val_at(constcvectorcv,size_tindex,void*memb)
{
memcpy(memb,cv->cv_pdata+index*cv->cv_size,cv->cv_size);
return0;
}
intcvector_rm(constcvectorcv,citeratoriter)
{
citeratorfrom;
citeratorend;
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
from=iter;
end=cvector_end(cv);
memcpy(from,from+cv->cv_size,end-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;
returnCVERM;
}
}
returnCVESUCCESS;
}
intcvector_rm_at(constcvectorcv,size_tindex)
{
citeratoriter;
iter=cv->cv_pdata+cv->cv_size*index;
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
returncvector_rm(cv,iter);
}
voidcv_info(constcvectorcv)
{
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;
}
voidcv_print(constcvectorcv)
{
intnum;
citeratoriter;
if(cvector_length(cv)==0)
fprintf(stderr,"file:%sfunc:%sline:%derror,nulllengthcvector!!/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:%dat:%d/n",num,cvector_iter_at(cv,iter));
}
return;
}
改进版
上面那份代码是在Linux下写的,如果是在Windows的VisulC++环境下编译似乎会出些问题,所以特别做了个改进版:
下面是更新后的代码:
cvector.h
#ifndef__CVECTOR_H__
#define__CVECTOR_H__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#defineMIN_LEN256
#defineCVEFAILED-1
#defineCVESUCCESS0
#defineCVEPUSHBACK1
#defineCVEPOPBACK2
#defineCVEINSERT3
#defineCVERM4
#defineEXPANED_VAL1
#defineREDUSED_VAL2
typedefvoid*citerator;
typedefstruct_cvector*cvector;
#ifdef__cplusplus
extern"C"{
#endif
cvectorcvector_create(constsize_tsize);
voidcvector_destroy(constcvectorcv);
size_tcvector_length(constcvectorcv);
intcvector_pushback(constcvectorcv,void*memb);
intcvector_popback(constcvectorcv,void*memb);
size_tcvector_iter_at(constcvectorcv,citeratoriter);
intcvector_iter_val(constcvectorcv,citeratoriter,void*memb);
citeratorcvector_begin(constcvectorcv);
citeratorcvector_end(constcvectorcv);
citeratorcvector_next(constcvectorcv,citeratoriter);
intcvector_val_at(constcvectorcv,size_tindex,void*memb);
intcvector_insert(constcvectorcv,citeratoriter,void*memb);
intcvector_insert_at(constcvectorcv,size_tindex,void*memb);
intcvector_rm(constcvectorcv,citeratoriter);
intcvector_rm_at(constcvectorcv,size_tindex);
/*fortest*/
voidcv_info(constcvectorcv);
voidcv_print(constcvectorcv);
#ifdef__cplusplus
}
#endif
#endif/*EOFfilecvector.h*/
cvector.c
#include"cvector.h"
#ifndef__gnu_linux__
#define__func__"unknown"
#defineinline__forceinline
#endif
#defineCWARNING_ITER(cv,iter,file,func,line)\
do{\
if((cvector_begin(cv)>iter)||(cvector_end(cv)<=iter)){\
fprintf(stderr,"var("#iter")warngoutofrange,"\
"atfile:%sfunc:%sline:%d!!\n",file,func,line);\
returnCVEFAILED;\
}\
}while(0)
struct_cvector
{
void*cv_pdata;
size_tcv_len,cv_tot_len,cv_size;
};
cvectorcvector_create(constsize_tsize)
{
cvectorcv=(cvector)malloc(sizeof(struct_cvector));
if(!cv)returnNULL;
cv->cv_pdata=malloc(MIN_LEN*size);
if(!cv->cv_pdata)
{
free(cv);
returnNULL;
}
cv->cv_size=size;
cv->cv_tot_len=MIN_LEN;
cv->cv_len=0;
returncv;
}
voidcvector_destroy(constcvectorcv)
{
free(cv->cv_pdata);
free(cv);
return;
}
size_tcvector_length(constcvectorcv)
{
returncv->cv_len;
}
intcvector_pushback(constcvectorcv,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;
returnCVEPUSHBACK;
}
}
memcpy((char*)cv->cv_pdata+cv->cv_len*cv->cv_size,memb,cv->cv_size);
cv->cv_len++;
returnCVESUCCESS;
}
intcvector_popback(constcvectorcv,void*memb)
{
if(cv->cv_len<=0)returnCVEPOPBACK;
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;
returnCVEPOPBACK;
}
}
returnCVESUCCESS;
}
size_tcvector_iter_at(constcvectorcv,citeratoriter)
{
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
return((char*)iter-(char*)cv->cv_pdata)/cv->cv_size;
}
intcvector_iter_val(constcvectorcv,citeratoriter,void*memb)
{
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
memcpy(memb,iter,cv->cv_size);
return0;
}
citeratorcvector_begin(constcvectorcv)
{
returncv->cv_pdata;
}
citeratorcvector_end(constcvectorcv)
{
return(char*)cv->cv_pdata+(cv->cv_size*cv->cv_len);
}
staticinlinevoidcvmemove_foreward(constcvectorcv,void*from,void*to)
{
size_tsize=cv->cv_size;
char*p;
for(p=(char*)to;p>=(char*)from;p-=size)memcpy(p+size,p,size);
return;
}
staticinlinevoidcvmemove_backward(constcvectorcv,void*from,void*to)
{
memcpy(from,(char*)from+cv->cv_size,(char*)to-(char*)from);
return;
}
intcvector_insert(constcvectorcv,citeratoriter,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;
returnCVEINSERT;
}
}
cvmemove_foreward(cv,iter,(char*)cv->cv_pdata+cv->cv_len*cv->cv_size);
memcpy(iter,memb,cv->cv_size);
cv->cv_len++;
returnCVESUCCESS;
}
intcvector_insert_at(constcvectorcv,size_tindex,void*memb)
{
citeratoriter;
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);
}
return0;
}
citeratorcvector_next(constcvectorcv,citeratoriter)
{
return(char*)iter+cv->cv_size;
}
intcvector_val(constcvectorcv,citeratoriter,void*memb)
{
memcpy(memb,iter,cv->cv_size);
return0;
}
intcvector_val_at(constcvectorcv,size_tindex,void*memb)
{
memcpy(memb,(char*)cv->cv_pdata+index*cv->cv_size,cv->cv_size);
return0;
}
intcvector_rm(constcvectorcv,citeratoriter)
{
citeratorfrom;
citeratorend;
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;
returnCVERM;
}
}
returnCVESUCCESS;
}
intcvector_rm_at(constcvectorcv,size_tindex)
{
citeratoriter;
iter=(char*)cv->cv_pdata+cv->cv_size*index;
CWARNING_ITER(cv,iter,__FILE__,__func__,__LINE__);
returncvector_rm(cv,iter);
}
voidcv_info(constcvectorcv)
{
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;
}
voidcv_print(constcvectorcv)
{
intnum;
citeratoriter;
if(cvector_length(cv)==0)
fprintf(stderr,"file:%sfunc:%sline:%derror,nulllengthcvector!!\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:%dat:%d\n",num,cvector_iter_at(cv,iter));
}
return;
}
main.cpp
#include"cvector.h"
intmain()
{
inti=1;
cvectorcv=cvector_create(sizeof(int));
cvector_pushback(cv,&i);
cvector_pushback(cv,&i);
cvector_pushback(cv,&i);
cvector_pushback(cv,&i);
cv_print(cv);
cvector_destroy(cv);
return0;
}