相关定义
- 前边讨论的线性表、串中的数据元素都是非结构的原子类型,即元素的值是不能再分解的;而数组和广义表中的数据元素本身也是数据结构,可以分解
- 顺序存储的次序约定问题:
语言类型 | 排序方式 | 例子 |
---|---|---|
C语言、PASCAL、拓展BASIC | 以行序为主序,把每个高维数组的第一个先依次表示出来 | a【0】【1】,a【1】【1】,a【2】【1】... |
FORTARN | 以列序为主序,把一个高维数组的所有元素先依次表示出来 | a【0】【1】,a【0】【2】,a【0】【3】... |
- 数组一旦被定义,其维数和维界就不再改变,因此一般不做插入或删除操作,除初始化和销毁数组外,只有存取和修改元素的操作
- 数组是可随机存取的数据结构:
(1)一旦规定维数和维界,便可以分配储存空间
(2)由下标对应便可取得相应元素的储存位置
需要用到知识(建议结合下边代码,更易理解)
- <stdarg.h>头文件
stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,这三个宏可获取参数数量可变的函数中的参数。可变参数的函数通在参数列表的末尾是使用省略号(,...)定义的。
类型 | 形式 | 描述 | 功能 |
---|---|---|---|
变量类型 | va_list | 这是一个适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型。 | |
宏 | void va_start(va_list ap, last_arg) | 这个宏初始化 ap 变量。其中,last_arg 是最后一个传递给函数的已知的固定参数,即省略号之前的参数。 | 这个宏的功能就是:输入第n个参数,输出的就是第n + 1个参数的地址值。va_start(ap, e); va_start 是一个宏,展开后,实际上相当于 ap = (char*)&e + sizeof(e); |
宏 | type va_arg(va_list ap, type) | 这个宏检索函数参数列表中类型为 type 的下一个参数。 | 返回当前地址指向的值后,将地址加一T var = va_arg(ap, T); 这个相当于 两句话, T var = *(T*)ap; ap+= sizeof(T); |
宏 | void va_end(va_list ap) | 这个宏允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义。 |
数组的顺序表示与相关操作的实现
- 数组的顺序表示
#define MAX_ARRAY_DIM 8
typedef struct{
ElemType *base;//数组元素基址
int dim;
int *bounds;//数组维界基址(记录数组每一维元素个数的一串数字的基址)
int *constants;//数组映像函数常量基址
} Array;
- 相关操作函数
Status InitArray(Array * A, int dim, ...);
Status DestroyArray(Array * A);
Status Value(Array A, ElemType *e ,...);
Status Assign(Array * A, ElemType e, ...);
Status Locate( Array A ,va_list ap,int *begin);//若ap指示的各下标值合法,则求出该元素在A中的相对地址begin
- 初始化数组
Status InitArray(Array * A, int dim, ...){
int total=1;
va_list ap;//可视为一个char*类型的指针
if(dim<1||dim>MAX_ARRAY_DIM){
return ERROR;
}
A->dim=dim;//得到数组维数
A->bounds=(int *)malloc(dim*sizeof(int));
if(!A->bounds){
return OVERFLOW;
}
va_start(ap,dim);
for(int i=0;i<dim;i++){
A->bounds[i]=va_arg(ap,int);
if(A->bounds[i]<0){
return ERROR;
}
total*=A->bounds[i];
}
va_end(ap);//得到记录数组维界的一串数字
A->base=(ElemType*)malloc(total*sizeof(ElemType));
if(!A->base){
return OVERFLOW;
}//根据数组元素总个数得到数组元素基址
A->constants=(int*)malloc(dim*sizeof(int));
if(!A->constants){
return OVERFLOW;
}
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 DestroyArray(Array * 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( Array A ,va_list ap,int *begin){
int index;
*begin=0;
for(int i=0;i<A.dim;i++){
index=va_arg(ap,int);
if(index<1||index>A.bounds[i]){
return ERROR;
}
*begin+=A.constants[i]*index;
}
return OK;
}
- 得到数组中某个地址的元素值
Status Value(Array A, ElemType *e ,...){
va_list ap;
int begin;
va_start(ap,*e);
if(!Locate(A,ap,&begin)){
return ERROR;
}
va_end(ap);
*e=*(A.base+begin);
return OK;
}
- 赋予数组中某个地址值
Status Assign(Array * A, ElemType e, ...){
va_list ap;
int begin;
va_start(ap,e);
if(!Locate(*A,ap,&begin)){
return ERROR;
}
va_end(ap);
*(A->base+begin)=e;
return OK;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。