如果我们按照C语言的方式存储它,也就是行优先存储的话,那么在内存中,它的形状是这样的:

cj-37.png

这种存储方式又被称作C contiguous array。 ( 推荐学习:web前端视频教程)

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

从行优先转换为列优先存储方式,与行优先相比,不同之处在于改变了数组维界基址的先后顺序, 从而改变了映像函数常量基址。

/** * @brief C语言 数组 列优先 实现 * @author wid * @date 2013-11-02 * * @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢! */  #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <assert.h>  #define OK 1 #define ERROR -1  #define MAX_DIM 8       ///允许的最大数组维数  typedef int ElemType;  typedef struct {     ElemType *base;         ///数组元素基址     int dim;                ///数组维数     int *bounds;            ///数组维界基址     int *constants;         ///数组映像函数常量基址 }Array;     ///数组结构  ///数组方法声明 int InitArray( Array *pArr, int nDim, ... );        ///初始化数组 pArr void DestroyArray( Array *pArr );                   ///销毁数组 pArr int Locate( Array *pArr, int nDim, va_list ap );                     ///定位下标指向的元素在数组中的位置 int Assign( Array *pArr, ElemType *elm, ... );      ///数组赋值 int Value( Array *pArr, ElemType *elm, ... );       ///数组取值  ///数组方法实现  /** * @brief 初始化数组 * * @param pArr 指向待初始化的数组 * @param nDim 数组的维数 * @param ... 数组各维数的长度 * * @return 初始化成功返回OK, 否则返回ERROR */ int InitArray( Array *pArr, int nDim, ... ) {      || nDim > MAX_DIM )         return ERROR;      ///初始化 pArr 数组维数属性     pArr->dim = nDim;      ///构造数组维界基址     pArr->bounds = (int *)malloc( nDim * sizeof(int) );     if( !pArr->bounds )         return ERROR;      , nElemCount = ;     va_list ap;     va_start( ap, nDim );      /// i = nDim - 1, 使列优先     ; i >= ; --i )     {         pArr->bounds[i] = va_arg( ap, int );          )             return ERROR;          nElemCount *= pArr->bounds[i];     }     va_end(ap);      ///初始化元素基址     pArr->base = (ElemType *)malloc( nElemCount * sizeof(ElemType) );     if( !pArr->base )         return ERROR;      ///初始化函数映像常数基址     pArr->constants = (int *)malloc( nDim * sizeof(int) );      ///递推求常量基址, 列优先     pArr->constants[nDim-] = ;      ; i >= ; --i )     {         pArr->constants[i] = pArr->bounds[i+] * pArr->constants[i+];     }      return OK; }  /** * @brief 销毁数组 pArr * * @param pArr 指向待销毁的数组 */ void DestroyArray( Array *pArr ) {     if( pArr->base )         free( pArr->base );      if( pArr->bounds )         free( pArr->bounds );      if( pArr->constants )         free( pArr->constants ); }  /** * @brief 定位数组下标指向的元素在数组中的位置 * * @param 指向的数组 * @param ... 数组的下标 * * @return 若下标合法, 返回下标在数组中的位置, 否则返回 ERROR */ int Locate( Array *pArr, int nDim, va_list ap ) {     , ind = , i = ;      ///列优先求地址     ; i >= ; --i )     {         ind = va_arg( ap, int );          ///使用断言, 确保下标合法         assert( ind >=  && ind < pArr->bounds[i] );          nPos += pArr->constants[i] * ind;     }     va_end(ap);      return nPos; }  /** * @brief 数组赋值 * * @param pArr 指向待赋值的数组 * @param elm 指向赋值元素 * @param nDim 数组维数 * @param ... 数组下标 * * @param 赋值成功返回 OK, 否则返回 ERROR */ int Assign( Array *pArr, ElemType *elm, ... ) {     ;     va_list ap;     va_start( ap, elm );     nPos = Locate( pArr, pArr->dim, ap );     *(pArr->base + nPos) = *elm;      return OK; }  /** * @brief 数组取值  */ int Value( Array *pArr, ElemType *elm, ... ) {     ;     va_list ap;     va_start( ap, elm );     nPos = Locate( pArr, pArr->dim, ap );     *elm = *(pArr->base + nPos);     printf( "addr = 0x%X\n", pArr->base + nPos );      return OK; }  int main() {     Array arr;      ///初始化一个三维数组, 大小为 2x3x5     InitArray( &arr, , , ,  );      ;     ///赋值测试     , m = , n = ;     ; i < ; ++i )         ; m < ; ++m )             ; n < ; ++n )             {                 a = i + m + n;                 Assign( &arr, &a, i, m, n );             }      ;     ///取值测试     ; i < ; ++i )         ; m < ; ++m )             ; n < ; ++n )             {                  Value( &arr, &b, i, m, n );                  printf( "[%d][%d][%d]=%d\n", i, m, n, b );             }      ///销毁数组     DestroyArray( &arr );      ; }

运行测试:

cj-38.png

更多相关文章

  1. 深入了解数组、List和ArrayList的区别
  2. c++如何从函数返回数组
  3. c语言数组求和的方法
  4. vb数组怎么定义
  5. c语言给数组赋值的3种形式
  6. c语言数组的定义及赋值
  7. c语言实现向有序数组中插入一个数并保持有序
  8. c语言如何定义字符串数组
  9. C语言中数组元素的下标下限是什么

随机推荐

  1. 初始化有EditText或AutoCompleteEditText
  2. MPAndroidChart项目实战(七)——自定义横向
  3. android开发视频教程 android培训入门教
  4. Android多屏幕适配之字体大小、行间距和
  5. 关于android中的gif实现
  6. Android:Camera2开发详解(上):实现预览、
  7. android实现百度地图定位
  8. Android 4.0新增WiFiDirect功能
  9. DisplayMetrics简介
  10. android View 概述