代码改变世界

C语言 数组 行优先 实现

2013-11-02 21:55  wid  阅读(1578)  评论(0编辑  收藏  举报

C语言数组结构行优先顺序存储的实现 (GCC编译)。

  1 /**
  2 * @brief C语言 数组 行优先 实现
  3 * @author wid
  4 * @date 2013-11-02
  5 *
  6 * @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!
  7 */
  8 
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <stdarg.h>
 12 #include <assert.h>
 13 
 14 #define OK 1
 15 #define ERROR -1
 16 
 17 #define MAX_DIM 8       ///允许的最大数组维数
 18 
 19 typedef int ElemType;
 20 
 21 typedef struct
 22 {
 23     ElemType *base;         ///数组元素基址
 24     int dim;                ///数组维数
 25     int *bounds;            ///数组维界基址
 26     int *constants;         ///数组映像函数常量基址
 27 }Array;     ///数组结构
 28 
 29 ///数组方法声明
 30 int InitArray( Array *pArr, int nDim, ... );        ///初始化数组 pArr
 31 void DestroyArray( Array *pArr );                   ///销毁数组 pArr
 32 int Locate( Array *pArr, int nDim, va_list ap );                     ///定位下标指向的元素在数组中的位置
 33 int Assign( Array *pArr, ElemType *elm, ... );      ///数组赋值
 34 int Value( Array *pArr, ElemType *elm, ... );       ///数组取值
 35 
 36 ///数组方法实现
 37 
 38 /**
 39 * @brief 初始化数组
 40 *
 41 * @param pArr 指向待初始化的数组
 42 * @param nDim 数组的维数
 43 * @param ... 数组各维数的长度
 44 *
 45 * @return 初始化成功返回OK, 否则返回ERROR
 46 */
 47 int InitArray( Array *pArr, int nDim, ... )
 48 {
 49     if( nDim < 1 || nDim > MAX_DIM )
 50         return ERROR;
 51 
 52     ///初始化 pArr 数组维数属性
 53     pArr->dim = nDim;
 54 
 55     ///构造数组维界基址
 56     pArr->bounds = (int *)malloc( nDim * sizeof(int) );
 57     if( !pArr->bounds )
 58         return ERROR;
 59 
 60     int i = 0, nElemCount = 1;
 61     va_list ap;
 62     va_start( ap, nDim );
 63     for( i = 0; i < nDim; ++i )
 64     {
 65         pArr->bounds[i] = va_arg( ap, int );
 66         if( pArr->bounds[i] < 0 )
 67             return ERROR;
 68 
 69         nElemCount *= pArr->bounds[i];
 70     }
 71     va_end(ap);
 72 
 73     ///初始化元素基址
 74     pArr->base = (ElemType *)malloc( nElemCount * sizeof(ElemType) );
 75     if( !pArr->base )
 76         return ERROR;
 77 
 78     ///初始化函数映像常数基址
 79     pArr->constants = (int *)malloc( nDim * sizeof(int) );
 80 
 81     ///递推求常量基址
 82     pArr->constants[nDim-1] = 1;
 83     for( i = nDim -2 ; i >= 0; --i )
 84     {
 85         pArr->constants[i] = pArr->bounds[i+1] * pArr->constants[i+1];
 86     }
 87 
 88     return OK;
 89 }
 90 
 91 /**
 92 * @brief 销毁数组 pArr
 93 *
 94 * @param pArr 指向待销毁的数组
 95 */
 96 void DestroyArray( Array *pArr )
 97 {
 98     if( pArr->base )
 99         free( pArr->base );
100 
101     if( pArr->bounds )
102         free( pArr->bounds );
103 
104     if( pArr->constants )
105         free( pArr->constants );
106 }
107 
108 /**
109 * @brief 定位数组下标指向的元素在数组中的位置
110 *
111 * @param 指向的数组
112 * @param ... 数组的下标
113 *
114 * @return 若下标合法, 返回下标在数组中的位置, 否则返回 ERROR
115 */
116 int Locate( Array *pArr, int nDim, va_list ap )
117 {
118     int nPos = 0, ind = 0, i = 0;
119 
120     for( i = 0; i < pArr->dim; ++i )
121     {
122         ind = va_arg( ap, int );
123 
124         ///使用断言, 确保下标合法
125         assert( ind >= 0 && ind < pArr->bounds[i] );
126 
127         nPos += pArr->constants[i] * ind;
128     }
129     va_end(ap);
130 
131     return nPos;
132 }
133 
134 /**
135 * @brief 数组赋值
136 *
137 * @param pArr 指向待赋值的数组
138 * @param elm 指向赋值元素
139 * @param nDim 数组维数
140 * @param ... 数组下标
141 *
142 * @param 赋值成功返回 OK, 否则返回 ERROR
143 */
144 int Assign( Array *pArr, ElemType *elm, ... )
145 {
146     int nPos = 0;
147     va_list ap;
148     va_start( ap, elm );
149     nPos = Locate( pArr, pArr->dim, ap );
150     *(pArr->base + nPos) = *elm;
151 
152     return OK;
153 }
154 
155 /**
156 * @brief 数组取值
157 
158 */
159 int Value( Array *pArr, ElemType *elm, ... )
160 {
161     int nPos = 0;
162     va_list ap;
163     va_start( ap, elm );
164     nPos = Locate( pArr, pArr->dim, ap );
165     *elm = *(pArr->base + nPos);
166 
167     return OK;
168 }
169 
170 //测试
171 int main()
172 {
173     Array arr;
174 
175     ///初始化一个三维数组, 大小为 2x3x5
176     InitArray( &arr, 3, 2, 3, 5 );
177 
178     int a = 0;
179     ///赋值测试
180     int i = 0, m = 0, n = 0;
181     for( i = 0; i < 2; ++i )
182         for( m = 0; m < 3; ++m )
183             for( n = 0; n < 5; ++n )
184             {
185                 a = i + m + n;
186                 Assign( &arr, &a, i, m, n );
187             }
188 
189     int b = 0;
190     ///取值测试
191     for( i = 0; i < 2; ++i )
192         for( m = 0; m < 3; ++m )
193             for( n = 0; n < 5; ++n )
194             {
195                  Value( &arr, &b, i, m, n );
196                  printf( "[%d][%d][%d]=%d\n", i, m, n, b );
197             }
198 
199     ///销毁数组
200     DestroyArray( &arr );
201 
202     return 0;
203 }

 运行测试:

若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢。