数组的动态存储方式
签名讲的数组都是在运行前就确定了数组大小,分配内存的。属于静态分配,这种存储方式对于在运行前不能确定长度的数组必须定义足够大的数组,以防止内存溢出。这样对于资源紧张的系统来说是非常不切实际的,所以就有了动态数组的概念。
下面生成一A[3][4][5][6]维的数组为例进行介绍
(1)目标是生成一个以base为基址的数组元素储存空间。本例中元素的个数总共是3*4*5*6
(2)各维数下标存入辅助向量bound,将bound[i]记为k[i],在本例中k0=3,k1=4,k2=5,k3=6。
(3)令函数映像Ci=ki+1*Ci+1,Cn-1,0<=i<=n-2,并将各个值存入const
如本例C3=1,C2=k3*C3=6,C1=k2*C2=30,C0=k1*C1=120
(4)取数组某个元素的相对地址
在本例中aijkp=i*C0+j*C1+k*C2+p*C3
(5)取数组的绝对地址
绝对地址=base+相对地址
明确了思路之后就可以写出动态数组的生成及操作算法
定义数组类型
#define MAX_DIM 8
typedef struct
{
datatype* base; //数组基址
int dim; //数组维数
int* bound; //辅助向量bound
int* const; //辅助向量 const
};
(1)数组生成算法
void SetArray(array* A,int n,int dim[])
{
int i;
int etotal=1; //元素总数
if(n<=0||n>MAX_DIM)
{
Error(n); //非法维数
}
else
{
A->dim=(int)malloc(sizeof(int));
if(!(A->dim))
{
return ; //分配内存失败
}
A->dim=n;
A->bound=(int*)malloc(n*sizeof(int ))
if(!(A->bound))
{
return ; //内存分配失败
}
for(i=0;i<n;i++)
{
if(dim[i]<0)
{
return ; //非法下标
}
A->bound[i]=dim[i];
etotal*=dim[i];
}
A->base=(datatype*)malloc(etotal*sizeof(datatype));
if(!(A->base))
{
return ; //分配内存失败
}
A->const=(int*)malloc(n*sizeof(int));
if(!(A->const))
{
return; //内存分配失败
}
A->const[n-1]=1;
for(i=n-2;i>=0;i--)
{
A->const[i]=(A->const[n+1])*(A->dim[n+1]);
}
}
}
(2)求元素相对地址的算法
int Index(array A,int dim[]) //A为数组元素,dim[]存放数组元素的下标
{
int i=1;
int j;
for(j=0;j<A.dim;j++)
{
if(dim[j]<0||dim[j]>A.bound[j])
{
return 0; //下标越界
}
else
{
i+=A.const[j]*dim[j];
}
}
return i;
}
(3) 取得数组元素的地址的算法
int Aget(array A,int dim[]) //取得元素的绝对地址
{
int i=1;
i=Index(A,dim[]);
if(i==0)
{
return 0;
}
else
{
i+=A.base;
}
return i;
}
浙公网安备 33010602011771号