时间:2021-05-19
如果我们按照C语言的方式存储它,也就是行优先存储的话,那么在内存中,它的形状是这样的:
这种存储方式又被称作C contiguous array。
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 ); ; }运行测试:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C语言行优先和列优先的问题深入分析摘要本文主要探讨的是“行优先”原则和“列优先”原则的问题。1.背景首先了解“行优先”和“列优先”的知识,这两种方式在数学上的直
详解C语言用malloc函数申请二维动态数组的实例C语言在程序运行中动态的申请及释放内存十分方便,一维数组的申请及释放比较简单。Sampleone#includ
1、要点(1)在C语言中没有字符串,只有字符,在python中的字符串hello,在C语言中是以字符数组在内存存放['h','e','l','l','o'],如
详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以
C/C++动态数组的创建的实例详解在C++语言中,二维动态数组主要使用指针的方法建立,以建立一个整数二维数组为例:#include#include#includ