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 
     64     /// i = nDim - 1, 使列优先
     65     for( i = nDim - 1; i >= 0; --i )
     66     {
     67         pArr->bounds[i] = va_arg( ap, int );
     68         if( pArr->bounds[i] < 0 )
     69             return ERROR;
     70 
     71         nElemCount *= pArr->bounds[i];
     72     }
     73     va_end(ap);
     74 
     75     ///初始化元素基址
     76     pArr->base = (ElemType *)malloc( nElemCount * sizeof(ElemType) );
     77     if( !pArr->base )
     78         return ERROR;
     79 
     80     ///初始化函数映像常数基址
     81     pArr->constants = (int *)malloc( nDim * sizeof(int) );
     82 
     83     ///递推求常量基址, 列优先
     84     pArr->constants[nDim-1] = 1;
     85     for( i = nDim -2 ; i >= 0; --i )
     86     {
     87         pArr->constants[i] = pArr->bounds[i+1] * pArr->constants[i+1];
     88     }
     89 
     90     return OK;
     91 }
     92 
     93 /**
     94 * @brief 销毁数组 pArr
     95 *
     96 * @param pArr 指向待销毁的数组
     97 */
     98 void DestroyArray( Array *pArr )
     99 {
    100     if( pArr->base )
    101         free( pArr->base );
    102 
    103     if( pArr->bounds )
    104         free( pArr->bounds );
    105 
    106     if( pArr->constants )
    107         free( pArr->constants );
    108 }
    109 
    110 /**
    111 * @brief 定位数组下标指向的元素在数组中的位置
    112 *
    113 * @param 指向的数组
    114 * @param ... 数组的下标
    115 *
    116 * @return 若下标合法, 返回下标在数组中的位置, 否则返回 ERROR
    117 */
    118 int Locate( Array *pArr, int nDim, va_list ap )
    119 {
    120     int nPos = 0, ind = 0, i = 0;
    121 
    122     ///列优先求地址
    123     for( i = pArr->dim - 1; i >= 0; --i )
    124     {
    125         ind = va_arg( ap, int );
    126 
    127         ///使用断言, 确保下标合法
    128         assert( ind >= 0 && ind < pArr->bounds[i] );
    129 
    130         nPos += pArr->constants[i] * ind;
    131     }
    132     va_end(ap);
    133 
    134     return nPos;
    135 }
    136 
    137 /**
    138 * @brief 数组赋值
    139 *
    140 * @param pArr 指向待赋值的数组
    141 * @param elm 指向赋值元素
    142 * @param nDim 数组维数
    143 * @param ... 数组下标
    144 *
    145 * @param 赋值成功返回 OK, 否则返回 ERROR
    146 */
    147 int Assign( Array *pArr, ElemType *elm, ... )
    148 {
    149     int nPos = 0;
    150     va_list ap;
    151     va_start( ap, elm );
    152     nPos = Locate( pArr, pArr->dim, ap );
    153     *(pArr->base + nPos) = *elm;
    154 
    155     return OK;
    156 }
    157 
    158 /**
    159 * @brief 数组取值
    160 
    161 */
    162 int Value( Array *pArr, ElemType *elm, ... )
    163 {
    164     int nPos = 0;
    165     va_list ap;
    166     va_start( ap, elm );
    167     nPos = Locate( pArr, pArr->dim, ap );
    168     *elm = *(pArr->base + nPos);
    169     printf( "addr = 0x%X
    ", pArr->base + nPos );
    170 
    171     return OK;
    172 }
    173 
    174 int main()
    175 {
    176     Array arr;
    177 
    178     ///初始化一个三维数组, 大小为 2x3x5
    179     InitArray( &arr, 3, 2, 3, 5 );
    180 
    181     int a = 0;
    182     ///赋值测试
    183     int i = 0, m = 0, n = 0;
    184     for( i = 0; i < 2; ++i )
    185         for( m = 0; m < 3; ++m )
    186             for( n = 0; n < 5; ++n )
    187             {
    188                 a = i + m + n;
    189                 Assign( &arr, &a, i, m, n );
    190             }
    191 
    192     int b = 0;
    193     ///取值测试
    194     for( i = 0; i < 2; ++i )
    195         for( m = 0; m < 3; ++m )
    196             for( n = 0; n < 5; ++n )
    197             {
    198                  Value( &arr, &b, i, m, n );
    199                  printf( "[%d][%d][%d]=%d
    ", i, m, n, b );
    200             }
    201 
    202     ///销毁数组
    203     DestroyArray( &arr );
    204 
    205     return 0;
    206 }

    运行测试:

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

  • 相关阅读:
    Scala 基础语法(二)
    Scala 基础语法(一)
    Scala 概述+scala安装教程+IDEA创建scala工程
    树链剖分【p2590】[ZJOI2008]树的统计
    树链剖分【p1505】[国家集训队]旅游
    状压DP【p1896】[SCOI2005]互不侵犯
    树链剖分【P3833】 [SHOI2012]魔法树
    KMP【UVA1328】 Period
    Trie树【UVA11362】Phone List
    线段树【p2801】教主的魔法
  • 原文地址:https://www.cnblogs.com/mr-wid/p/3404445.html
Copyright © 2011-2022 走看看