zoukankan      html  css  js  c++  java
  • 数组的顺序存储表示

    #include<stdio.h>
    #include<stdarg.h>         //标准头文件获取变长参数表,提供宏va_start,va_arg,va_end
    #include<stdlib.h>
    
    #define MAX_ARRAY_DIM 8    //定义数组的最大维度
    #define ERROR 0
    #define OK 1
    #define OVERFLOW -1
    typedef int ElemType;
    typedef int Status;
    
    typedef struct{
        ElemType * base;     //数组元素的基址,由InitArray分配
        int dim;            //维度
        int *bounds;       //数组的维界基址,由InitArray分配,指向一个数组B(存储数组A的各维度的元素的数目)
        int *constants;   //数组映像函数常量基址,由InitArray分配,指向一个数组C, 它存放了"数组A各个维度上的数字加一时, 元素在线性结构L上所移动的距离
    }Array;
    
    //初始化数组
    Status InitArray(Array *A, int dim, ...)
    {
        //统计元素总数目,进而分配数组的基址
        int elemtotal = 1;
        int i;
    
    
        //判断维度是否合法
        if(dim < 1 || dim > MAX_ARRAY_DIM)
        {
            return ERROR;
        }
    
        A->dim = dim;
        //分配维界基址
        A->bounds = (int *)malloc(dim * sizeof(int));
        if(!A->bounds)
        {
            exit(OVERFLOW);
        }
    
        va_list ap;
    
        va_start(ap, dim);
    
        for(i = 0; i < dim; ++i)
        {
            A->bounds[i] = va_arg(ap, int);
            if(A->bounds[i] < 0)
            {
                return ERROR;
            }
            elemtotal *= A->bounds[i];      //统计元素数目
        }
    
        va_end(ap);
    
        A->base = (ElemType *)malloc(elemtotal*sizeof(ElemType));    //分配数组的基地址
        if(!A->base)
        {
            exit(-1);
        }
    
        //求映像函数的常数ci,即保存指针增减移动的元素的个数
        A->constants = (int *)malloc(dim * sizeof(int));
        if(!A->constants)
        {
            exit(-1);
        }
    
        A->constants[dim-1] = 1;      //最高维,指针每次移动一个元素单位
    
        for(i = dim - 2; i >= 0; --i)
        {
            //第i维的指针每次移动的距离 = i+1维元素的数目 * i+1维指针每次移动的距离
            A->constants[i] = A->bounds[i+1] * A->constants[i+1];
        }
    
        return OK;
    }
    
    //销毁数组
    Status DestroyArray(Array *A)
    {
        //判断数组的基址是否为空,free(NULL)是不允许的
        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;
    }
    
    //取指定的位置的元素的相对地址,方便后续取值与赋值
    Status Locate(Array A, va_list ap, int *off)
    {
        int i;
        int tag;
        //若各维度合法,求出该元素的相对地址
        (*off) = 0;          //相对于第一个元素的地址
    
        for(i = 0; i < A.dim; ++i)
        {
            tag = va_arg(ap, int);
            if(tag < 0 || tag > A.bounds[i])
            {
                return ERROR;          //维度不合法
            }
            (*off) = (*off) + tag * A.constants[i];       //注意是tag,不明白画图三维数组
        }
    
        return OK;
    }
    
    //取指定下标元素的值,赋值给e
    Status Value(Array A, ElemType *e, ...)
    {
        int result, off;
        va_list ap;
        va_start(ap, *e);
        if((result = Locate(A, ap, &off)) <= 0)
        {
            return result;
        }
    
        (*e) = *(A.base + off);
        return OK;
    }
    
    Status Assign(Array *A, ElemType e, ...)
    {
        va_list ap;
        va_start(ap, e);
        int result, off;
    
        if((result = Locate(*A, ap, &off)) <= 0)
        {
            return result;
        }
    
        *(A->base + off) = e;
        return OK;
    }
    
    
    int main(void)
    {
        Array A;
        int e;
    
        InitArray(&A, 3, 3, 3, 3);
        Assign(&A, 10, 0, 1, 2);
        Value(A, &e, 0, 1, 2);
        printf("%d", e);
        return 0;
    }
    
  • 相关阅读:
    使用SOCKET实现TCP/IP协议的通讯
    多线程和高并发的区别
    linq学习之join
    Winform 创建桌面快捷方式并开机启动
    引领5G行业化,广和通荣获“IoT创新大奖”
    全方面的了解超宽带信号高速采集记录回放系统
    浅谈智慧灯杆的通信网建设要求
    逆向工程,调试Hello World !程序(更新中)
    融合智能将成时代方舟?中科创达技术大会向未来答疑
    第十一届蓝桥杯赛后体会和经验分享
  • 原文地址:https://www.cnblogs.com/zcxhaha/p/11181854.html
Copyright © 2011-2022 走看看