c语言数组算递推吗,详解C语言数组中是以列优先吗

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

807b34ffc5eed6aaf1ea4d955d21167d.png

这种存储方式又被称作C contiguous array。

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

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

/**

* @brief C语言 数组 列优先 实现

* @author wid

* @date 2013-11-02

*

* @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!

*/

#include

#include

#include

#include

#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 );

;

}

运行测试:

39f5f59d7341df79da9af8d7ea73b8d5.png

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值