C語言 數組 行優先 實現

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 或程序缺陷, 請留言反饋, 謝謝。                                                                                                                                                                                                                                                                                                                                                            測試

相關文章
相關標籤/搜索