数组的顺序存取表示

预备知识

库函数<stdarg.h>

C语言该头文件定义了变量类型va_list和三个宏,分别是va_start()、va_arg()、va_end(); 主要功能是在函数参数未知的情况下获取函数参数;即下面类型的函数;

//参数固定的函数
void add(int total,num1,num2,num3) 
 
//参数未知的函数,格式以 ...结束
void add(int total,...)  
  • va_list用来定义变量对象
  • va_start(参数1,参数2):初始化变量,参数1为变量对象,参数2为传入函数的最后 一个固定参数,即省略号前面的第一个,上面代码就是total
  • va_arg():获取参数
  • va_end():函数返回

应用:

#include<stdarg.h>
int Sum(int num, ...)
{
    int i, val = 0;
    va_list ap;
    va_start(ap, num);
    for(i = 0; i < num; i++)
    {
        val += va_arg(ap, int);
    }
    va_end(ap);
    return val;
}
int main()
{
    printf("10, 20, 30的和为 %d\n", Sum(3, 10, 20, 30));
    printf("4, 5, 6, 7的和为 %d\n", Sum(4, 4, 5, 6, 7));
    return 0;
}

/*  运行结果
10, 20, 30的和为 60
4, 5, 6, 7的和为 22
Program ended with exit code: 0
*/

数组和线性表

存储的元素都必须属于同一数据类型,数组实质是存储结构,用一组连续的存储单元存放数据,而线性表则是数据结构中的一种逻辑结构,线性表需要借助数组来实现顺序存储结构;一维数组就相当于定长的线性表,二维数组可以看作每个元素都是定长线性表的定长线性表,多维数组可以看作线性表的推广;

几乎所有的程序设计语言中都将数组作为固有类型,通过数组不仅可以实现线性表的顺序存储结构,同样也可以用来构造栈、队列、串的顺序存储结构;

多维数组

int a[10][10]  //定义一个整型的二维数组

二维数组可以看作每个数据元素存放的都是一个一维数组,三维数组可以看作每个元素都是一个二维数组的一维数组;同理,四维等也是如此;

多维数组的顺序存储表示

顺序存储中是先开辟一个元素基址base,根据元素的下标值,找到其元素地址,然后进行存取操作,

获取元素地址(以二维数组为例 )

int a[3][3]
//假设a中元素为1、2、3、4、5、6、7、8、9
//图形表示
1 2 3
4 5 6
7 8 9
/*
上面二维数组的存储结构实际上是 
base[0]==1,base[1]==2、...、base[8]==9
然而以二维数组表示则是
a[0][0]==1,a[0][1]==2,a[0][2]==3
a[1][0]==4,a[1][1]==5,a[1][3]==6
....

因此假如我们要在a[1][1]存入4,则要找到其对应的base[x]的x值;
从上面的图形我们可以看出x=1*3+0*1=3;

上面求元素基址的方法推广到一般规律,加入我们要求四维数组s[a][b][c][d]中s[2][2][1][4]的base[x]中x的值,x=2*b+2*c+1*d+4*1;

代码:

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

#define MAX_ARRAY_DIM 8  //最大维度数

typedef struct
{
    int *base;    //元素基址
    int dim;      //维数
    int *bounds;  //维界基址,存放各维元素数
    int *constants;//映像函数常数
}Array;
//初始化
void InitArray(Array *A,int dim,...)
{
    int elemtotal=1;
    if(dim<1||dim>MAX_ARRAY_DIM)
        printf("维数不合法!");
    A->dim=dim;
    A->bounds=(int *)malloc(dim*sizeof(int));
    if(!A->bounds)
        exit(0);
    
    va_list ap;
    va_start(ap, dim);
    for(int i=0;i<dim;i++)
    {
        A->bounds[i]=va_arg(ap, int);
        if(A->bounds[i]<0)
            exit(0);
        elemtotal*=A->bounds[i];
    }
    va_end(ap);
    
    A->base=(int *)malloc(sizeof(int));
    if(!A->base)
        exit(0);
    
    A->constants=(int *)malloc(dim*sizeof(int));
    if(!A->constants)
        exit(0);
    A->constants[dim-1]=1;
    for(int i=dim-2;i>=0;i--)
    {
        A->constants[i]=A->bounds[i+1]*A->constants[i+1];
    }
    
}
//销毁数组
int DestroyArray(Array *A)
{
    if(!A->base)
        return 0;
    free(A->base); A->base=NULL;
    if(!A->bounds)
        return 0;
    free(A->bounds);A->bounds=NULL;
    if(!A->constants)
        return 0;
    free(A->constants);A->constants=NULL;
    return 1;
}
//求基址
int Locate(Array A,va_list ap)
{
    int off=0,ind;
    for(int i=0;i<A.dim;i++)
    {
        ind=va_arg(ap, int);
        if(ind<0||ind>=A.bounds[i])
            exit(0);
        off+=A.constants[i]*ind;
    }
    return off;
}
//给出下表求其值
int Value(Array A,...)
{
    int num;
    int result;
    va_list ap;
    va_start(ap, A);
    result=Locate(A, ap);
    num=A.base[result];
    return num;
}
//给出下标为其赋值
void Assign(Array *A,int e,...)
{
    va_list ap;
    va_start(ap, e);
    int result;
    result=Locate(*A, ap);
    *(A->base+result)=e;
}

int main()
{
    Array A,*p;
    p=&A;
    int num;
    InitArray(p, 3,2,3,4);
    Assign(p, 0,1,2,3);//a[1][2][3]赋值为0
    num=Value(A, 1,2,3);
    printf("%d\n",num);
   
    return 0;
}
//运行结果  0

猜你喜欢

转载自www.cnblogs.com/zhulmz/p/11742017.html