版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/82950915
无论在数值计算亦或是非数值计算,数组均有广泛的运用。因此,绝大多数 高级语言都将数组设为固有数据类型,
数组可看做普通线性表的推广,普通数组的各项操作都不会引起元素的插入或删除,故数组使用顺序存储结构。
假设每个数据元素占L个存储单元,则二维数组A中任一元素a[i][j]的存储位置可以表示为
LOC(i,j)=LOC(0,0)+(b2*i+j)L
LOC(i,j)是a[i][j]的存储位置,LOC(0,0)是a00的存储位置,即二维数组A的起始存储位置,也称为基地址或基址。
推广到一般情况:
LOC(j1,j2,...jn)=LOC(0,0,...0) +
求和公式即为n维数组的映像函数。通过它可以得到元素在数组中的地址。
首先是辅助宏的定义:
#include <stdarg.h> //标准头文件 ,提供宏va_start va_arg va_end
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define UNDERFLOW -2
#define MAX_ARRAY_DIM 8 //假设数组维数最大是8
va_list ap;//定义ap为va_list类型 是存放变长参数表信息的数组
数组的存储结构定义:
typedef struct{
ElemType *base; //数组元素基址 由InitArray分配
int dim; //数组维数
int *bounds;//数组维界基址 由InitArray分配
int *constants; //数组映像函数常量基址 由InitArray分配
}Array;
若维数dim和各维长度合法 则构造函数相应的数组A 并返回OK。
Status InitArray(Array &A,int dim,...){
//若维数dim和各维长度合法 则构造函数相应的数组A 并返回OK
if(dim<1||dim>MAX_ARRAY_DIM)
return ERROR;
A.dim=dim;
A.bounds=(int *)malloc(dim*sizeof(int));
if(!A.bounds) //存储分配失败
exit(OVERFLOW);
int elemtotal=1,i;
va_start(ap,dim); //开启ap 从dim的下一个参数为第一个参数
for(i=0;i<dim;i++){ //若各维度合法 存入A.bounds 并求出元素总数elemtotal
A.bounds[i]=va_arg(ap,int); //不断找下一个参数类型为int的参数
if(A.bounds[i]<0)
return UNDERFLOW;
elemtotal*=A.bounds[i];
}
va_end(ap);//关闭ap
A.base=(ElemType *)malloc(elemtotal*sizeof(ElemType));
if(!A.base)//存储分配失败
exit(OVERFLOW);
A.constants=(int *)malloc(dim*sizeof(int));
//求映像函数的常数 并存入A.constans[i-1],i=1...dim;
if(!A.constants)
exit(OVERFLOW); //存储分配失败
A.constants[dim-1]=1;
for(i=dim-2;i>=0;i--)
A.constants[i]=A.bounds[i+1]*A.constants[i+1];
return OK;
}
销毁数组A.
Status DestroyArray(Array &A){
//销毁数组A
if(!A.base)
return ERROR;
free(A.base);
A.base=NULL;
if(!A.bounds)
return ERROR;
free(A.bounds);
A.bounds=NULL;
if(!A.constants)
return ERROR;
free(A.constants);
A.constants=NULL;
return OK;
}
若ap指示的下标值合法 则求出该元素在A中相对位置off.
Status Locate(Array A,va_list ap,int &off){
//若ap指示的下标值合法 则求出该元素在A中相对位置off
int ind;
off=0;
for(int i=0;i<A.dim;i++){
ind=va_arg(ap,int);//获取当前参数
if(ind<0||ind>=A.bounds[i]) //参数不合法
return OVERFLOW;
off+=A.constants[i]*ind;//合法地址改变
}
return OK;
}
A是n维数组e是元素变量 随后是n个下标值,若各下标不越界 则e赋值为所指定的A的元素值 并返回OK..
Status Value(Array A,ElemType *e,...){
//VC中 之前的形参不能用引用(怪不得老是测试失败)
//A是n维数组e是元素变量 随后是n个下标值
//若各下标不越界 则e赋值为所指定的A的元素值 并返回OK
int result,off;
va_start(ap,e);
if((result=Locate(A,ap,off))<=0) //如果参数下标有不合法
return result;
*e=*(A.base+off);//否则传回e
return OK;
}
A是n维数组 e为元素变量 随后是n个下标值,若下标不越界 则将e的值赋给所指定的A的元素 并返回OK
Status Assign(Array &A,ElemType e,...){
//A是n维数组 e为元素变量 随后是n个下标值
//若下标不越界 则将e的值赋给所指定的A的元素 并返回OK
int result,off;
va_start(ap,e);
if((result=Locate(A,ap,off))<=0)//如果参数下标有不合法
return result;
*(A.base+off)=e;
return OK;
}