0.
数组是我们很熟悉的一种数据类型。为了加深对数组的理解,我们在这里用抽象数据类型的形式讨论数组的定义和实现。
1.
数组的几个基本操作如下:
InitArray(); //构造数组
DestroyArray(); //销毁数组
Value(); //取值
Assign(); //给数组的某个元素赋值
数组一般不作插入和删除的操作,所以采用顺序的存储结构表示数组。
在线性代数或者矩阵分析中都学过矩阵,一个2x3的矩阵,可以看成是一个2维列向量,这个列向量的每一个元素又是一个3维行向量。或者这个矩阵可以看成是一个3维行向量,这个行向量的每一个元素是一个2维列向量。这是关于矩阵的一种理解方式。
类似的,在C语言中,我们可以把二维数组看成是一个一维数组,这个一维数组的每一个元素又是一个一维数组。以此类推,一个n维数组可以理解成数据元素为n-1维数组的一维数组。
typedef ElemType Array2[m][n];
等价于:
typedef ElemType Array1[n];
typedef Array1 Array2[m];
采用顺序的存储结构表示数组 示意图如下:
左侧是以列序为主序,右侧是以行序为主序。BASIC,C语言和PASCAL都是以行序为主序的存储结构,FORTRAN是以列序为主序的存储结构。这篇博客默认数组采用行序为主序的存储结构。
下面介绍称为n维数组的映像函数。
这个函数根据数组下标可以直接计算某一个元素的存储位置。
LOC(j1,j2,...,jn)
=LOC(0,0,...,0)+(b2∗...∗bn∗j1+b3∗...∗bn∗j2+.......+bn∗jn−1+jn)∗L
=LOC(0,0,...,0)+∑ni=1ciji
注:
LOC(0,0,...,0)是数组的起始地址,每个数据元素占L个存储单元,bi每个维度的大小,
cn=L,ci−1=bi∗ci,这里一旦确定数组的各维长度,ci就是常数了。
这个公式看起来有点复杂,实际上很容易理解,你举个具体的例子,尝试用这个公式算一下,一切都明朗了。
下面就是具体的实现过程
代码写的很简单的(根据这段代码加深下对数组的理解)
#include<stdio.h>
#include<stdlib.h>
#define MAX_ARRAY_DIM 8
typedef int ElemType;
typedef struct {
ElemType *base; //存储数据
int dim;
int *bounds; //存储每个维度的大小
int *constants; //存储映射函数中的c_i
} Array;
int InitArray(Array *A,int dim)
{
//一旦建立数组,数组的维数以及各维的长度就确定下来了
int i;
int elemtotal=1;
if(dim<1||dim>MAX_ARRAY_DIM)
return -1;
A->dim=dim;
A->bounds=(int *)malloc(dim*sizeof(int));
if(!A->bounds)
exit(-1);
for(i=0;i<dim;i++)
{
scanf("%d",&((A->bounds)[i]));
if(A->bounds[i]<0)
return -1;
elemtotal*=A->bounds[i];
}
A->base=(ElemType *)malloc(elemtotal*sizeof(ElemType));
if(!A->base)
exit(-1);
A->constants=(int *)malloc(dim*sizeof(int));
if(!A->constants)
exit(-1);
(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;
}
int DestoryArray(Array *A)
{
if(!A->base)
return -1;
free(A->base);
A->base=NULL;
if(!A->bounds)
return -1;
free(A->bounds);
A->bounds=NULL;
if(!A->constants)
return -1;
free(A->constants);
A->constants=NULL;
return 1;
}
int Value(Array A,ElemType *e)
{
int i,ind;
int off=0;
for(i=0;i<A.dim;i++)
{
scanf("%d",&ind);
if(ind<0||ind>A.bounds[i])
exit(-1);;
off+=ind*A.constants[i];
}
*e=*(A.base+off); //off是偏移量
return 1;
}
int Assign(Array *A,ElemType e)
{
int i,ind;
int off=0;
for(i=0;i<A->dim;i++)
{
scanf("%d",&ind);
if(ind<0||ind>A->bounds[i])
exit(-1);
off+=ind*A->constants[i];
}
*(A->base+off)=e; //这里指针相加,编译器会自动乘以指向元素的大小
return 1;
}
void main()
{
Array A;
InitArray(&A,3);
int e=3;
Assign(&A,e);
printf("%d",Value(A,&e));
}
2.关于数组的题目
http://www.cnblogs.com/graphics/archive/2010/08/24/1761620.html#link06
这个链接在我的收藏夹里保存了快一年了,之前有次搜东西的时候发现的,排版什么的的看着都很舒服。