数组的顺序存储

数组这个比较抽象,实质就是将多维的数组降到一维来存储,
程序中:
bounds:存的就是指定维度下的各维长度
constants:个人理解觉得其充当一个便利分隔块的作用,用于定位,即每一个维度如果下标增加1,那个对应到内存空间(即一维下)的下标应该增加多少

比如以4维数组为例: 
for(i = 0; i < dim ; i++)
{
    A.bounds[i] = va_arg(ap,int);
   //printf("A.bounds[%d]-----%d\n",i,A.bounds[i]);
}

则
A.bounds[0]=4
A.bounds[1]=5
A.bounds[2]=6
A.bounds[3]=7

A.constants[dim-1]=1;
for (i=dim-2;i>=0;--i)
{
     A.constants=A.bounds * A.constants;
}

A.constants[3] = 1
A.constants[2] = 7
A.constants[1] = 6*7
A.constants[0] = 5*6*7
对于(2,0,0,0)这个下标的元素,应该越过前面的(0,0,0,0)~(0,4,5,6)和(1,0,0,0)~(1,4,5,6)这两大块,而这两大块中的每一块都有5*6*7个元素
对于(3, 2, 2, 5)这个下标的元素,那么定位公式应该是:
t = 3*A.constants[0] + 2*A.constants[1] + 2*A.constans[2] + 5*A.constans[3]

 

Code

/*#include<stdarg.h>用于获取不确定个数的参数

  数据类型:va_list:用于保存va_arg、va_end所需的信息

  提供宏va_start:使va_list指向起始的参数
        va_arg:检索参数
        va_end:释放va_list
*/
#include<bits/stdc++.h>
#define Max_ARRAY_DIM  8 ///假设数组维数最大为8
#define ERROR 0
#define OK 1
#define UNDERFLOW -2
#define OVERFLOW 1
using namespace std;

typedef int Status;
typedef int elemtype;

typedef struct
{
    elemtype *base; /// 数组元素的基址,由Init分配
    int dim;         ///数组维数
    int *bounds;    /*数组维界基址,由Init分配
                    (woc,这个解释很是官方,懵的一笔,其实就是指定维度下的各维长度)*/
    int *constants; ///数组映像函数常量基址,由Init分配
}Array;

///若维数 n 和各维长度合法,则构造相应的数组A,并返回OK
Status Init(Array &A, int dim,...)
{
/***************************************************************************/  
    /*  这里的dim是维数,后面...表示不定参数(是各维度的长度也就是大小)。
        比如Init(A,2,3,4);表示2维数组,3行4列
    */
    if(dim < 1 || dim >  Max_ARRAY_DIM)
        return ERROR;
    A.dim = dim;
    A.bounds = (int *)malloc(dim * sizeof(int));
    if(!A.bounds)
        exit(OVERFLOW);
        
/***************************************************************************/  
    ///若各维长度合法,则存入A.bounds,并求出A的元素总数elemtotal
    va_list ap;
    int i,elemtotal = 1;
    va_start(ap,dim);   ///ap为va_list类型,是存放变长参数表信息的数组
    for(i = 0; i < dim ; i++)
    {
        A.bounds[i] = va_arg(ap,int);
        //printf("A.bounds[%d]-----%d\n",i,A.bounds[i]);
        if(A.bounds[i] < 0)
            return UNDERFLOW;
            /*
                underflow 堆栈下溢,常赋值为负数
                原因:指针调用错误、系统栈空间过小、指针被错误修改
            */
        elemtotal *= A.bounds[i]; ///各维数的大小相乘,即这个维数下的体积,也就是元素总个数
    }
    va_end(ap);
/***************************************************************************/  
    A.base = (elemtype*)malloc(elemtotal * sizeof(elemtype));/*这一步其实是关键,多维转化存到一维下*/
    if(!A.base)
        exit(OVERFLOW);
/***************************************************************************/        
    ///求映像函数的常数Ci,并存入A.constants[i-1],i = 1.....dim
    A.constants = (int *)malloc(dim * sizeof(int));
    if(!A.constants)
        exit(OVERFLOW);
    A.constants[dim - 1] = 1; /// L = 1,指针的增减以元素的大小为单位
    for(i = dim - 2; i>=0; i--){
        A.constants[i] = A.bounds[i+1] * A.constants[i+1];
    }
    return OK;
}

///销毁数组
Status DestroyArray(Array &A)
{
    if(!A.base)
        return ERROR;
    free(A.base);
    A.base = NULL;

    if (!A.bounds)
        return ERROR;
    free(A.bounds);
    A.bounds = NULL;

    if (!A.constants)
        return ERROR;
    free(A.constants);
    A.constants = NULL;
    return OK;
}

///若ap指示的各下标值合法,则求出该元素在A中相当地址off
Status Locate(Array A, va_list ap, int &off)
{
    off = 0;
    int i, ind;
    for(i = 0; i < A.dim; i++)
    {
        ind  = va_arg(ap,int);
        if(ind < 0 || ind >= A.bounds[i])
            return OVERFLOW;
        off += A.constants[i]*ind;
    }
    return OK;
}
/*
A是n维数组,e为元素变量,后面是n 个下标值。
若各下标不超界,则e被赋值为所指定的A的元素值,并返回OK。
e=A[i1][i2]…[in];
*/
Status Value(Array A,elemtype &e,...)
{
    va_list ap;
    int off,result;
    va_start(ap,e);
    if((result = Locate(A,ap,off)) <= 0)
        return result;
    e = *(A.base + off);
    return OK;
}

/*
A是n维数组,e为元素变量,随后是n 个下标值。
若下标不超界,则将e的值赋给所指定的A的元素,并返回OK。
A[i1][i2]…[in] =e;
*/
Status Assign(Array &A, elemtype e,...)
{
    va_list ap;
    int result , off;
    va_start(ap,e);
    if((result = Locate(A,ap,off)) <= 0)
        return result;
    *(A.base + off) = e;
    return OK;
}

int main()
{
    Array a;
    int i,j,m,n;
    elemtype x;
    cin>>m>>n;
    Init(a,2,m,n);
    for(i=0;i<m;i++)
        for (j=0;j<n;j++)
            Assign(a,(i+1)*(j+1),i,j);
    for(i=0;i<m;i++)
    {
        for (j=0;j<n;j++)
        {
            Value(a,x,i,j);
            cout<<"   "<<x;
        }
        if( i != m - 1)
            cout<<'\n';
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/mcgrady_ww/p/7900475.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值