数据结构_数组
被窝使人懒惰 ORZ
​​​My blog​

/*
<stdarg.h> 利用函数va_start、va_arg和va_end提供遍历未知数目和类型的函数参数表的功能
va_start (va_list ap,x) 初始化ap,使其指向所在函数的参数x之后的第一个参数
va_avg (va_list ap,类型) 返回ap当前指向的参数值,并修改ap,使得ap指向下一个参数("类型",为参数类型)
va_end (va_list ap) 用在所有参数处理完毕之后,表示ap使用完毕
*/
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <stdarg.h>//用于存取可变长参数表
#define Max_array_dim 8 //假设最大维数为8
#define ElemType int
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
ElemType *base;//数组元素基址
int dim;//维数
int *bounds;//数组各维 长度信息保存区 基址(存储了每个维度所在的地址) 比如a[3][4][5] bounds[0]=3 bounds[1]=4 bounds[2]=5
int *constants; //数组映像函数常量的基址,映像函数就是用以根据数组下标快速计算其存储位置
}Array;

/*若维度dim和各维度长度合法,则构造相应的数组A*/
Status Init_Array(Array *A,int dim,...)
{
int elemtotal=1;//元素总值
va_list ap;// 定义一个va_list 变量 ap
if(dim<1||dim>Max_array_dim)
return False;

A->dim=dim;
A->bounds=(int *)malloc(dim*sizeof(int));//为bounds申请空间
if(!(A->bounds)) return False;
//求bounds
va_start(ap,dim);//初始化ap


for(int i=0;i<dim;i++)
{
A->bounds[i]=va_arg(ap,int);
/*
获取参数,调用va_arg,它的第一个参数是ap,第二个参数是要获取的参数的指定类型,
然后返回这个指定类型的值,
并且把 ap 的位置指向变参表的下一个变量位置;
*/
if(A->bounds[i]<0) return UNDERFLOW; //在math.h中定义为4
elemtotal *= A->bounds[i];
}
va_end(ap);//获取所有参数之后,将ap指向NULL

//求映像函数的常数ci,并存入A.constants[i-1],i=1,2,...dim;
A->base=(ElemType *)malloc(elemtotal * sizeof(ElemType));
if(!(A->base)) return False;
A->constants = (int *) malloc(dim*sizeof(int));
if(!(A->constants)) return False;
A->constants[dim-1]=1;
for(int i=dim-2;i>=0;i--)
A->constants[i]=A->bounds[i+1] * A->constants[i+1];

return OK;
}

/*销毁数组*/
Status Destory_Array(Array *A)
{
if(A->base)
{
free(A->base);
A->base=NULL;
}
if(A->bounds)
{
free(A->bounds);
A->bounds=NULL;
}
if(A->constants)
{
free(A->constants);
A->constants=NULL;
}
return OK;
}

/*若ap指示的各下标值合法,则求出该元素在A中的相对地址off*/
Status Locate_Array(Array A,va_list ap,int *off)
{
*off=0;
for(int i=0;i<A.dim;i++)
{
int ind=va_arg(ap,int);
// cout<<"ind: "<<ind<<endl;
if(ind<0||ind>=A.bounds[i])
return False;
*off+=A.constants[i]*ind;//位置
// cout<<"A.constants "<<i<<" "<<A.constants[i]<<" "<<ind<<endl;
// cout<<"off: "<<" "<<*off<<endl;
}
return OK;
}

/*若各下标不超界,则e赋值为所指定的A的元素值*/
Status Value_Array(ElemType *e,Array A,...)
{
Status result;
va_list ap;
int off;
va_start(ap,A);
if((result=Locate_Array(A,ap,&off))<=0) return result;
*e=*(A.base+off);
va_end(ap);
return OK;
}

/*若下标不超界,则将e的值赋给所指定的A的元素*/
Status Assign_Array(Array *A,ElemType e,...)
{
Status result;
va_list ap;
int off;
va_start(ap,e);
if((result=Locate_Array(*A,ap,&off))<=0) return result;
*(A->base+off)=e;
// cout<<"!!!!: "<<e<<endl;
va_end(ap);
return OK;
}
int main()
{
Array A;
int dim=3,bound1=2,bound2=3,bound3=4;//a[2][3][4]数组
ElemType e;
Init_Array(&A,dim,bound1,bound2,bound3);//构造3*4*5的三维数组
cout<<"dim: "<<dim<<endl;
cout<<"bounds: ";
for(int i=0;i<dim;i++)//顺序输出A.bounds 各维长度
{
cout<<A.bounds[i]<<" ";
}
cout<<endl;

cout<<"constants: "<<endl;
for(int i=0;i<dim;i++)//顺序输出A.constants
{
cout<<"constants"<<"["<<i<<"]: "<<A.constants[i]<<endl;
}
int cnt=1;
for(int i=0;i<bound1;i++)
{
for(int j=0;j<bound2;j++)
{
for(int k=0;k<bound3;k++)
{
Assign_Array(&A,cnt++,i,j,k); //将cnt赋值给A[i][j][k] cnt++
Value_Array(&e,A,i,j,k);//将A[i][j][k]赋值给e
cout<<"A["<<i<<"]"<<"["<<j<<"]"<<"["<<k<<"]"<<"= "<<e<<" ";
}
cout<<endl;
}
cout<<endl;
}
// cout<<"A.base: "<<endl;
// for(int i=0;i<bound1*bound2*bound3;i++)
// {
// cout<<A.base[i]<<" ";
// if(i%(bound2*bound3)==bound2*bound3-1) cout<<endl;
// }
//查找第x,y,z的值
cout<<"Search: ";
int x=2,y=2,z=2;
Value_Array(&e,A,x,y,z);
cout<<"A["<<x<<"]"<<"["<<y<<"]"<<"["<<z<<"]"<<"="<<e<<endl;
Destory_Array(&A);
return 0;
}

/*

constants[i]简写为coni,bounds[i]简写为boni那么
con i= bon[i+1]*con[i+1]=bon[i+1]*bon[i+2]*con[i+2]
= bon[i+1]*bon[i+2]*bon[i+3]*con[i+3] = bon[i+1]*bon[i+2]*bon[i+3]*...*bon[dim-1]
*/