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, ... )
{
if( nDim < || nDim > MAX_DIM )
return ERROR; ///初始化 pArr 数组维数属性
pArr->dim = nDim; ///构造数组维界基址
pArr->bounds = (int *)malloc( nDim * sizeof(int) );
if( !pArr->bounds )
return ERROR; int i = , nElemCount = ;
va_list ap;
va_start( ap, nDim );
for( i = ; i < nDim; ++i )
{
pArr->bounds[i] = va_arg( ap, int );
if( pArr->bounds[i] < )
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-] = ;
for( i = 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 )
{
int nPos = , ind = , i = ; for( i = ; i < pArr->dim; ++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, ... )
{
int nPos = ;
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, ... )
{
int nPos = ;
va_list ap;
va_start( ap, elm );
nPos = Locate( pArr, pArr->dim, ap );
*elm = *(pArr->base + nPos); return OK;
} //测试
int main()
{
Array arr; ///初始化一个三维数组, 大小为 2x3x5
InitArray( &arr, , , , ); int a = ;
///赋值测试
int i = , m = , n = ;
for( i = ; i < ; ++i )
for( m = ; m < ; ++m )
for( n = ; n < ; ++n )
{
a = i + m + n;
Assign( &arr, &a, i, m, n );
} int b = ;
///取值测试
for( i = ; i < ; ++i )
for( m = ; m < ; ++m )
for( n = ; n < ; ++n )
{
Value( &arr, &b, i, m, n );
printf( "[%d][%d][%d]=%d\n", i, m, n, b );
} ///销毁数组
DestroyArray( &arr ); return ;
}

 运行测试:

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

C语言 数组 行优先 实现的更多相关文章

  1. C语言 数组 列优先 实现

    C语言数组结构列优先顺序存储的实现 (GCC编译). 从行优先转换为列优先存储方式, 与行优先相比, 不同之处在于改变了数组维界基址的先后顺序, 从而改变了映像函数常量基址. /** * @brief ...

  2. C/C++遍历二维数组,列优先(column-major)比行优先(row-major)慢,why?

    C/C++遍历二维数组,列优先(column-major)比行优先(row-major)慢,why? 简单粗暴的答案:存在Cache机制! 稍微啰嗦一点:CPU访问内存(读/写,遍历数组的话主要是读) ...

  3. 二维数组 A[m][n] 按行优先和按列优先的 下标地址转换公式

    设二维数组 A[m][n] 按行优先存储, 每个元素占 p 个字节, 则 Loc(i, j) 的地址为 (i * n + m) * p, 第 i 行前面有 i 行, 每行有 n 个元素, 加上 第 i ...

  4. C/C++——C语言数组名与指针

    版权声明:原创文章,转载请注明出处. 1. 一维数组名与指针 对于一维数组来说,数组名就是指向该数组首地址的指针,对于: ]; array就是该数组的首地址,如果我们想定义一个指向该数组的指针,我们可 ...

  5. 不可或缺 Windows Native (5) - C 语言: 数组

    [源码下载] 不可或缺 Windows Native (5) - C 语言: 数组 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 数组 示例cArray.h #ifn ...

  6. C语言数组

    在C语言中,对于三维或三维以上数组的使用并没有很好的支持,而且使用率也非常的低,后面会对三维数组做一些简单的分析,这篇文章主要以二维数组来探讨一些C语言中数组使用的相关概念和技巧. 1 一个var[i ...

  7. C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

    1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...

  8. Go语言数组的使用

    Go 语言数组 Go 语言提供了数组类型的数据结构. 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. 相对于去声明number0 ...

  9. 【嵌入式开发】C语言 命令行参数 函数指针 gdb调试

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21551397 | http://www.hanshul ...

随机推荐

  1. iOS nib file owner

    nib文件中的file owner属性,设定后app在运行时加载nib文件的过程中会通过file owner重新建立nib文件中描述的控件与其在file owner中对应的IBOutlet或IBAct ...

  2. 移动端调试工具-Weinre

    java版本安装和调试 首先需要下载 weinre, weinre目前支持Windows与MacOS, 本文中以Windows版为例. 下载地址:http://people.apache.org/~p ...

  3. Brn系列商城3.0测试版正式发布,欢迎大家下载测试

    BrnShop商城3.0测试版和BrnMall商城3.0测试版正式发布,欢迎大家下载测试(点击下载).测试结束后将会发布正式版和MySQL版本. 测试过程中发现bug欢迎大家给我们反馈,反馈邮箱:br ...

  4. Oracle SQL优化一(常见方法)

    1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...

  5. 03-JAVA方法

    答:我发现这两个方法的返回类型以及参数类型不一样. package 汉诺塔问题; /**汉诺塔问题*作者:徐浩军 日期:16.10.16 天气:晴*/ public class TowersOfHan ...

  6. 02-JAVA中的基本语法

    第一个动手动脑: 首先用枚举类型定义两个变量,然后判断两个变量是否引用同一对象,在判断枚举类型是否是原始数据类型,再从字符串中转换,最后列出所有的对象. 很明显,这两个变量都是枚举类型,但是这两个变量 ...

  7. 安装 composer SSL operation failed with code 1

    gavin@webdev:~> curl -sS https://getcomposer.org/installer | php Downloading... Download failed: ...

  8. POJ Ant Counting DP

    dp[i][j]表示前i种蚂蚁组成元素个数为j的集合有多少种. 则dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + ... + dp[i-1][ max(0,j-a[i]) ...

  9. php protected封装

    <?//父类class father{ public function a(){     echo 'father->a()'.'<br>';  echo "func ...

  10. (Python )模块、包

    本节开始学习模块的相关知识,主要包括模块的编译,模块的搜索路径.包等知识 1.模块 如果我们直接在解释器中编写python,当我们关掉解释器后,再进去.我们之前编写的代码都丢失了.因此,我们需要将我们 ...