动态数组

最近看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));
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值