/***********************************************************************
程序功能: 数组的顺序存储实现
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> //标准头文件,提供宏va_start , va_arg, va_end
//用于存取变长参数
#define ERROR 0
#define OVERFLOW -2
#define UNDERFLOW -1
#define OK 1
#define MAX_ARRAY_DIM 8 //假设数组维数的最大值为8
typedef int ElemType;
typedef int Status;
typedef struct
{
ElemType *base; //数组元素基址,由InitArray分配;
int dim; //数组维数
int *bounds; //数组维界基址, 由InitArray分配
int *constants; //数组映像函数常量基址,由InitArray分配
}Array;
Status InitArray(Array &A, int dim, ...)
{
if(dim < 1 || dim > MAX_ARRAY_DIM)
return ERROR;
A.dim = dim;
A.bounds = (int *) malloc (dim*sizeof(int));
if(!A.bounds)
return OVERFLOW;
int elemTotal =1; //存放元素的总个数
va_list arg_ptr; //存放变长参数表信息的数组
va_start(arg_ptr,dim); //第二个参数是第一个可变参数的前一个参数,固定的
for(int i = 0; i < dim; ++i)
{
A.bounds[i] = va_arg(arg_ptr, int);//用va_arg返回可变的参数,并赋值给整数A.bounds[i].
//va_arg的第二个参数是你要返回的参数的类型,这里是int型.
if(A.bounds[i] < 0)
return UNDERFLOW;
elemTotal *= A.bounds[i];
}
va_end(arg_ptr);
A.base = (ElemType *) malloc (elemTotal * sizeof(ElemType));
if(!A.base)
return OVERFLOW;
A.constants = (int *) malloc (dim * sizeof(int));
if(!A.constants)
return OVERFLOW;
A.constants[dim - 1] = 1;//L=1,指针的增减以元素的大小为单位
for(int index = dim -2; index >= 0; --index)
{
A.constants[index] = A.constants[index + 1] * A.bounds[index + 1];
}
return OK;
}
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;
}
Status Locate(const Array &A, va_list ap, int &off)
{
//若ap指示的各下标值合法,则求出该元素在A中相对地址off
off = 0;
int index;
for(int i = 0; i < A.dim; ++i)
{
index = va_arg(ap, int);
if(index < 0 || index >= A.bounds[i])
return OVERFLOW;
off += A.constants[i] * index;
}
return OK;
}
Status Value (const Array &A, ElemType *e, ...)
{
//A是n维数组,e为元素变量,随后是n个下标值
//若各下标不越界,则e赋值为所指定的A的元素值,并返回OK
va_list ap;
va_start(ap, e);
int result;
int off;
if((result = Locate(A,ap,off)) <= 0)
return result;
*e = *(A.base + off);
va_end(ap);
return OK;
}
Status Assign(Array &A, ElemType e, ...)
{
//A是n维数组,e为元素变量,随后是n个下标值
//若下标不越界,则将e的值赋给所指定的A的元素,并返回OK
va_list ap;
va_start(ap, e);
int off;
int result;
if((result = Locate(A, ap, off)) <= 0)
return result;
*(A.base + off) = e;
va_end(ap);
return OK;
}
int main()
{
Array A;
int testArray[2][3] = {{1, 2, 3},{4, 5, 6}};
InitArray(A,2,2,3);
printf("A.dim = %d\n",A.dim);
printf("各维的长度是:\n");
for(int index = 0; index < A.dim; ++index)
{
printf("%d\t",A.bounds[index]);
}
printf("\n数组的常量基址是:\n");
for(index = 0; index < A.dim; ++index)
{
printf("%d\t",A.constants[index]);
}
printf("\n");
for(int i = 0; i < 2; ++i)
{
for(int j=0; j < 3; ++j)
{
Assign(A, testArray[i][j], i, j); //对数组进行赋值
}
}
int value;
printf("创建的数组中的元素为:\n");
for(i = 0; i < 2; ++i)
{
for(int j = 0; j < 3; ++j)
{
Value(A, &value,i,j);
printf("%d\t",value);
}
printf("\n");
}
printf("按照数组的线性序列输出元素,即利用基址地址输出元素:\n");
for( i = 0; i < 2 * 3; i++)
{
printf("第%d个元素=%3d\t",i+1,A.base[i]);
if( (i+1) % 3 == 0 )
printf("\n");
}
return 0;
}
数据结构:数组的顺序存储实现
最新推荐文章于 2024-06-17 21:39:08 发布