/*
<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]
 */

 


年轻也需要有所作为( ・´ω`・ )