最近看c语言接口与实现,觉得这才是代码
在c中,数组是编译时指定,也可用malloc等函数进行运行时确定,这篇文字主要是提供更通用性的ADT
好的注释就是代码,所以这段代码没写注释
#ifndef ARRAY_H
#define ARRAY_H
#define T Array
typedef struct T *T;
extern T Array_new(int length,int size);
extern void Array_free(T *a);
extern int Array_length(T a);
extern int Array_size(T a);
extern void *Array_get(T a,int i);
extern void *Array_put(T a,int i,void *e);
extern void Array_resize(T a,int size);
extern T Array_cop(T a,int length);
#undef T
#endif
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include"array.h"
#include"arep.h"
#include"mem.h"
#define T Array
void arep_init(T a,int len,int size,void *ary)
{
assert(a);
assert(ary&&len>0||ary==NULL&&len==0);
a->length=len;
a->size=size;
if(len>0)a->_array=(char *)ary;
else a->_array=NULL;
}
T Array_new(int length,int size)
{
T a;
NEW(a,T);
if(length>0)
arep_init(a,length,size,CALLOC(length,size,void *));
else arep_init(a,length,size,NULL);
return a;
}
void Array_free(T *a)
{
FREE((*a)->_array);
FREE(*a);
}
void *Array_get(T a,int i)
{
return a->_array+i*a->size;
}
void *Array_put(T a,int i,void *e)
{
assert(i>=0&&i<a->length);
assert(a);
memcpy(a->_array+i*a->size,e,a->size);
return e;
}
int Array_length(T a)
{
return a->length;
}
int Array_size(T a)
{
return a->size;
}
void Array_resize(T a,int len)
{
assert(len>=0&&a);
if(len==0)
FREE(a->_array);
else if(a->length==0)
a->_array=ALLOC(len*a->size,char *);
else
RESIZE(a->_array,len*a->size,char *);
a->length=len;
}
T Array_cop(T a,int len)
{
T cop;
int min;
assert(len>=0&&a);
cop=Array_new(len,a->size);
min=len<a->length?len:a->length;
memcpy(cop->_array,a->_array,min*a->size);
return cop;
}
#ifndef AREP_H
#define AREP_H
#define T Array
struct T
{
int length;
int size;
char *_array;
};
extern void arep_init(T a,int len,int size,void *ary);
#undef T
#endif
#ifndef MEM_H
#define MEM_H
extern void *Mem_alloc(long nbyte,const char *file,int line);
extern void *Mem_calloc(long count,long nbyte,const char *file,int line);
#define ALLOC(nbyte,type) \
(type)Mem_alloc((nbyte),__FILE__,__LINE__)
#define CALLOC(count,nbyte,type) \
(type)Mem_calloc((count),(nbyte),__FILE__,__LINE__)
#define NEW(pt,type) ((pt)=ALLOC((long)sizeof *(pt),type))
#define NEW0(pt,type)((pt)=CALLOC(1,(long)sizeof *(pt),type))
extern void Mem_free(void *pt,const char *file,int line);
#define FREE(pt) ((void)(Mem_free((pt),__FILE__,__LINE__),pt=0))
extern void *Mem_resize(void *pt,long nbyte,const char *file,int line);
#define RESIZE(pt,nbyte,type) ((pt)=(type)Mem_resize((pt),(nbyte),__FILE__,__LINE__))
#endif
#include"mem.h"
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
const char *Mfail="allocation failed";
void *Mem_alloc(long nbyte,const char *file,int line)
{
void *pt;
assert(nbyte>0);
pt=malloc(nbyte);
if(pt==NULL)
{
if(file==NULL)fprintf(stderr,Mfail);
else fprintf(stderr,Mfail,file,line);
fflush(stderr);
abort();
}
return pt;
}
void *Mem_calloc(long count,long nbyte,const char *file,int line)
{
void *pt;
assert(nbyte>0);
pt=calloc(count,nbyte);
if(pt==NULL)
{
if(file==NULL)fprintf(stderr,Mfail);
else fprintf(stderr,Mfail,file,line);
fflush(stderr);
abort();
}
return pt;
}
void Mem_free(void *pt,const char *file,int line)
{
if(pt)free(pt);
}
void *Mem_resize(void *pt,long nbyte,const char *file,int line)
{
assert(nbyte>0);
pt=realloc(pt,nbyte);
if(pt==NULL)
{
if(file==NULL)fprintf(stderr,Mfail);
else fprintf(stderr,Mfail,file,line);
fflush(stderr);
abort();
}
return pt;
}
#include"array.h"
#include<stdio.h>
#define T Array
int main()
{
T a=Array_new(100,sizeof(int));
int i;T b;
for(i=0;i<100;i++)
Array_put(a,i,&i);
for(i=0;i<100;i++)
printf("%d",*(int *)Array_get(a,i));
printf("\n");
b=Array_cop(a,50);
Array_resize(a,50);
for(i=0;i<50;i++)
printf("%d",*(int *)Array_get(a,i));
Array_free(&a);
a=NULL;
printf("\n");
for(i=0;i<50;i++)
printf("%d",*(int *)Array_get(b,i));
}