/* 数据结构C语言版 数组的顺序存储表示和实现 P93 编译环境:Dev-C++ 4.9.9.2 日期:2011年2月8日 */ #include <stdio.h> #include <malloc.h> typedef int ElemType; // Array.h 数组的顺序存储表示 #include<stdarg.h> // 标准头文件,提供宏va_start,va_arg和va_end, // 用于存取变长参数表 #define MAX_ARRAY_DIM 8 // 假设数组维数的最大值为8 typedef struct { ElemType *base; // 数组元素基址,由InitArray分配 int dim; // 数组维数 int *bounds; // 数组维界(每一维的长度)基址,由InitArray分配 int *constants; // 数组映象函数常量基址,由InitArray分配,可以看 // 成是存储每一维的下标换算成对应数组元素地址的方法 }Array; // 若维数dim和各维长度合法,则构造相应的数组A,并返回1 int InitArray(Array *A,int dim,...) { int elemtotal=1, i; // elemtotal是元素总值 va_list ap; //首先定义了一个va_list变量,这个参看变参的使用 if(dim<1||dim>MAX_ARRAY_DIM) return 0; (*A).dim=dim; //初始化数组的维度 (*A).bounds=(int *)malloc(dim*sizeof(int)); //初始化数组的数组维界基址 if(!(*A).bounds) exit(0); //对已定义va_list变量进行初始化,第二个变量为可变变量的前第一个参数dim va_start(ap,dim); for(i=0;i<dim;++i) { //保存各维的长度,va_arg取得类型为int的可变参数值 (*A).bounds[i]=va_arg(ap,int); if((*A).bounds[i]<0) return 0; // 在math.h中定义为4 elemtotal*=(*A).bounds[i]; //记录数组中的元素个数 } va_end(ap); //结束可变参数的获取 //初始化数组元素的基址,分配定长的存储空间 (*A).base=(ElemType *)malloc(elemtotal*sizeof(ElemType)); if(!(*A).base) exit(0); //初始化数组映像函数常量基址 (*A).constants=(int *)malloc(dim*sizeof(int)); if(!(*A).constants) exit(0); (*A).constants[dim-1]=1; for(i=dim-2; i>=0; --i) (*A).constants[i]=(*A).bounds[i+1]*(*A).constants[i+1]; return 1; } // 销毁数组A,将分配了地址的元素进行释放置空 int DestroyArray(Array *A) { if((*A).base) { free((*A).base); (*A).base=NULL; } else return 0; if((*A).bounds) { free((*A).bounds); (*A).bounds=NULL; } else return 0; if((*A).constants) { free((*A).constants); (*A).constants=NULL; } else return 0; return 1; } // Value()、Assign()调用此函数 // 若ap指示的各下标值合法,则求出该元素在A中的相对地址off int Locate(Array A, va_list ap, int *off) { int i,ind; *off=0; for(i=0;i<A.dim;i++) { ind=va_arg(ap,int); if(ind<0||ind>=A.bounds[i]) return 0; *off+=A.constants[i]*ind; } return 1; } // ...依次为各维的下标值,若各下标合法,则e被赋值为A的相应的元素值 // 在VC++中,...之前的形参不能是引用类型 int Value(ElemType *e,Array A,...) { va_list ap; int result; int off; va_start(ap,A); if((result=Locate(A,ap,&off))==0) // 调用Locate() return result; *e=*(A.base+off); return 1; } // ...依次为各维的下标值,若各下标合法,则将e的值赋给A的指定的元素 int Assign(Array *A,ElemType e,...) { va_list ap; int result; int off; va_start(ap,e); if((result=Locate(*A,ap,&off))==0) // 调用Locate() return result; *((*A).base+off)=e; return 1; } int main() { Array A; int i,j,k,*p,dim=3,bound1=3,bound2=4,bound3=2; // a[3][4][2]数组 ElemType e,*p1; InitArray(&A,dim,bound1,bound2,bound3); // 构造3*4*2的3维数组A p=A.bounds; printf("A.bounds="); for(i=0;i<dim;i++) // 顺序输出A.bounds 维数 printf("%d ",*(p+i)); p=A.constants; printf("\nA.constants="); for(i=0;i<dim;i++) // 顺序输出A.constants printf("%d ",*(p+i)); printf("\n%d页%d行%d列矩阵元素如下:\n",bound1,bound2,bound3); for(i=0;i<bound1;i++) { for(j=0;j<bound2;j++) { for(k=0;k<bound3;k++) { // 将i*100+j*10+k赋值给A[i][j][k] Assign(&A,i*100+j*10+k,i,j,k); Value(&e,A,i,j,k); // 将A[i][j][k]的值赋给e printf("A[%d][%d][%d]=%2d ",i,j,k,e); // 输出A[i][j][k] } printf("\n"); } printf("\n"); } p1=A.base; printf("A.base=\n"); for(i=0;i<bound1*bound2*bound3;i++) // 顺序输出A.base { printf("%4d",*(p1+i)); if(i%(bound2*bound3)==bound2*bound3-1) printf("\n"); } DestroyArray(&A); system("pause"); return 0; } /* 输出效果: A.bounds=3 4 2 A.constants=8 2 1 3页4行2列矩阵元素如下: A[0][0][0]= 0 A[0][0][1]= 1 A[0][1][0]=10 A[0][1][1]=11 A[0][2][0]=20 A[0][2][1]=21 A[0][3][0]=30 A[0][3][1]=31 A[1][0][0]=100 A[1][0][1]=101 A[1][1][0]=110 A[1][1][1]=111 A[1][2][0]=120 A[1][2][1]=121 A[1][3][0]=130 A[1][3][1]=131 A[2][0][0]=200 A[2][0][1]=201 A[2][1][0]=210 A[2][1][1]=211 A[2][2][0]=220 A[2][2][1]=221 A[2][3][0]=230 A[2][3][1]=231 A.base= 0 1 10 11 20 21 30 31 100 101 110 111 120 121 130 131 200 201 210 211 220 221 230 231 请按任意键继续. . . */