zoukankan      html  css  js  c++  java
  • 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
    ", i, m, n, b );
    197             }
    198 
    199     ///销毁数组
    200     DestroyArray( &arr );
    201 
    202     return 0;
    203 }

     运行测试:

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

  • 相关阅读:
    DB设计原则
    英文地址[转]
    ICollection
    雅虎优化14条
    vue过滤器
    php中echo(),print(),print_r()之间的区别
    jQ中对attr()方法的理解
    浅析call和apply的不同
    浅析call和apply
    PHP是弱类型语言,自动转换,强制转换
  • 原文地址:https://www.cnblogs.com/mr-wid/p/3404232.html
Copyright © 2011-2022 走看看