数组的顺序表示和实现:利用可变参数列表实现多维数组的创建
2014-06-09 09:27
471 查看
数组的顺序表示和实现:利用可变参数列表实现多维数组的创建
对于可变参数列表的详细介绍,参见文章:《C语言函数的可变参数列表》。完整代码可在CSDN资源中搜索《数组的顺序存储表示和实现:利用可变参数列表实现多维数组的创建,元素赋值等操作》进行下载。#include<stdarg.h> #include<stdio.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define MAX_ARRAY_DIM 8 //设置数组的最大维度 typedef int ElemType; typedef struct{ ElemType *base; //存数数组数据项的基址 int dim; //存储数组的维度 int *bounds; //数组维界基址存数每个维度的长度 int *constants; //存储每个维度指针的增减的单位,即数组在该维度的下标增加一对应几个</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:12px;">ElemType类型的单位。如三维整型数组的第一维空间下标增减一对应一个整型内存空间的偏移,第二维空间的下表增减1对应第一维的长度个整型内存空间的偏移,第三维空间的下表增减1对应前两维的长度相乘个整型内存空间的偏移</span></span><span style="font-size:14px;"> }Array;</span>
void InitArray( Array *ary, int dim, ... );//根据参数构造数组ary int Locate( Array *ary, va_list ap, int *offset );//判断给定的下标范围是否符合要求 int Assign( Array *ary, ElemType e, ... );//将数组的某个单元赋值为e int Value( Array *ary, ElemType *e, ... ); void Destroy( Array *ary ); //若维数和随后的各维长度合法,则构造相应的数组 //注意此函数不能对数组元素进行初始化 void InitArray( Array *ary, int dim, ... ) { va_list var_arg; //可变参数列表 int i; int elemtotal = 1; //用于统计数组元素的总个数 if( dim < 1 || dim > MAX_ARRAY_DIM ){ //如果维度小于1或大于限定的最大维度,则返回错误并结束程序执行 printf( "InitArray Error: WRONG DIM!\n" ); exit( EXIT_FAILURE ); } va_start( var_arg, dim ); //可变参数的第一个参数 ary->dim = dim; //将数组维度置为参数中给出的维度 ary->bounds = ( int *)malloc( dim *sizeof( int ) ); //为存数每个维度的长度的数组分配空间 if( ary->bounds ){ //分配成功则将dim后的参数按顺序赋给相应的内存单元 for( i = 0; i < dim; i++ ){ *( ary->bounds + i ) = va_arg( var_arg, int ); if( *( ary->bounds + i ) <= 0 ){ printf( "InitArray Error: WRONG ARRAY BOUNDS!\n" ); exit( EXIT_FAILURE ); } elemtotal *= *( ary->bounds + i ); //数组的总元素的个数等于各个维度长度的乘积 } va_end( var_arg ); } else{ printf( "InitArray Error: OVERFLOW!\n" ); exit( EXIT_FAILURE ); } ary->base = ( ElemType * )malloc( sizeof( ElemType ) * elemtotal ); //为存放数组元素的数据块分配内存单元 if( !ary->base ){ printf( "InitArray Error: OVERFLOW!\n" ); exit( EXIT_FAILURE ); } ary->constants = ( int * )malloc( sizeof( int ) * dim ); //为存放指针增减单位的数据块分配内存单元 if( !ary->constants ){ printf( "InitArray Error: OVERFLOW!\n" ); exit( EXIT_FAILURE ); } *( ary->constants + dim - 1 ) = 1; //最后一个维度的指针的增减以元素的大小为单位 for( i = dim -2; i >= 0; i-- ){ *( ary->constants + i ) = *( ary->bounds + i + 1 ) * *( ary->constants + i + 1 ); //前一个维度指针增减一对应的单位是后一个维度的单位乘以后一个维度的长度 } }
//判断给出的下标值是否合法,若合法,则计算出对应基址的偏移 int Locate( Array *ary, va_list ap, int *offset ) //第二个参数类型为va_list,即为数组元素的下标组合,根据该可变参数列表的所有值来求得offset { int i; int ind; //每个维度对应的下标值 *offset = 0; for( i = 0; i < ary->dim; i++ ){ ind = va_arg( ap, int ); if( ind < 0 || ind >= *( ary->bounds + i ) ) return FALSE; else{ *offset += ind * (*( ary->constants + i )); } } return TRUE; } //将数组给定下标的元素赋值为e int Assign( Array *ary, ElemType e, ... ) //省略号后的参数就是需要被赋值的数组元素对应的下标 { va_list var_arg; int offset; va_start( var_arg, e ); if( Locate( ary, var_arg, &offset ) ){ *( ary->base + offset ) = e; return TRUE; } else return FALSE; } //将数组给定下标的元素的值赋给e,与Assign的赋值方向是相反的 int Value( Array *ary, ElemType *e, ... ) //省略号后的参数就是需要赋值给e的数组元素对应的下标 { va_list var_arg; int offset; va_start( var_arg, e ); if( Locate( ary, var_arg, &offset ) ){ *e = *( ary->base + offset ); return TRUE; } else return FALSE; } void Destroy( Array *ary ) { if( !ary->base || !ary->bounds || !ary->bounds ) printf( "Destroy Error!\n" ); else{ free( ary->base ); free( ary->bounds ); free( ary->constants ); } }
相关文章推荐
- 创建函数利用可变参数列表的形式模拟实现printf的功能
- 利用可变参数列表简单实现printf函数的功能
- C语言之利用可变参数列表实现简易的printf
- 利用数组创建的顺序表实现各种功能
- 利用数组创建的顺序表实现各种功能
- [C语言]利用stdarg.h来实现可变参数列表
- 数组的顺序存储表示和实现-数据结构
- 数组的顺序表示和实现
- JQuery插件第二十个:利用json数组即时创建明细列表
- 数组的顺序表示和实现
- C中可变参数列表函数的实现
- [C/C++]函数参数的入栈顺序与可变参数的实现
- 数组的顺序结构表示和实现
- 数组的顺序表示与实现
- 利用可变参数函数清空多个数组
- C使用 stdarg 宏来实现函数的可变参数列表
- 函数参数的入栈顺序与可变参数的实现
- C语言多维数组的存储表示和实现
- 可变参数 函数(可变参列表—2) 实现小型日志文件
- 可变参数列表及printf函数的实现