• 多维数组的实现


       数组一旦被定义了,它的维数和维界就不会变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素。数组一般分为行序和列许。一般系统都是用的行许。
    以2维数组a[m][n]为例
    列序:
    a[0][0]  a[1][0] ...... a[m-1][0]
    .............
    a[m-1][0] a[m-1][1] ...... a[m-1][n-1]

    行序列:
    a[0][0]  a[1][0] ...... a[m-1][0]
    .............
    a[0][n-1] a[1][ [n-1 ] ...... a[m-1][n-1]
    数据一般使用连续的地址存储。计算的方法为 (i, j) = &a + (b) + j;//b 一维元素的个数
    推广到多维数组中(j1, j2, j3,.....,jn) = (b2*b3*...*bn * j1 + b3*b4*...*bn*j2 + .....+bn *jn-1 + jn)
    例如:已知数组a[5][4][10]。求a[2][3][4] 的地址;
    j1=2、j2 = 3、j3 = 4;b1=5、b2=4、b3=10;
    a[2][3][4]=b2*b3*j1+b3*j2+j3=4*10*2+10*3+4;

    下面为代码实现。(以下代码是我在ubuntu中简单测试通过。如在别的系统中无法运行,请谅解。本代码只经过简单的测试,如果出现问题,请谅解。)
    /*
    *created by Reage at 2013 March 28
    *description: 数组的实现,包含创建、赋值、访问、打印
    *
    *blog:http://blog.csdn.net/rentiansheng
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    
    
    #define MAXDIM 4
    
    typedef struct Array
    {
        int dim;
        int *ptr;
        int *bounds;
        int *base_add;
    }Array;
    
    int array_init(Array *a, int dim, ...);
    int array_set_value(Array *a, int value, ...);
    int array_print_line(Array *a);
    int array_get_value(Array *a, ...);
    void array_destory(Array *a);
    
    int main(int argc, char *argv[])
    {
        Array a;
        int i = 0;
        int j;
        int total = 1;
        array_init(&a, 2, 4, 6);
        
        for(; i < 4; i++)
        {
            for(j = 0; j < 6; j++)
            {
                array_set_value(&a, total++, i, j);
            }
        }
    
        array_print_line(&a);
        for(i = 0; i < 4; i++)
        {
            for(j = 0; j < 6; j++)
            {
                printf("%-7d",array_get_value(&a,  i, j));
            }
            printf("\n");
        }
        array_destory(&a);
    }
    
    int array_init(Array * a, int dim, ...)
    {
        if(1 > dim || 8 < dim)
            return -1;
        a->dim = dim;
    
        va_list ap;
        int i;
        long total = 1;
    
        a->bounds = (int *)malloc(dim * sizeof(int));
        
        va_start(ap, dim);
        for(i = 0; i < dim; i++)
        {
            a->bounds[i] = va_arg(ap, int);
            total *= a->bounds[i];
        }
        va_end(ap);
    
        a->ptr = (int *) malloc(total * sizeof(int));
    
        a->base_add = (int *) malloc(dim * sizeof(int));
        a->base_add[dim -1] = 1;
        i = dim -2;
        for(; i >= 0; i--)
        {
            a->base_add[i] = a->base_add[i+1] * a->bounds[i+1];
        }
    
        return 0;
    }
    
    #define FREE(x) if(NULL != (x)) free(x)
    
    void array_destory(Array *a)
    {
        FREE(a->ptr);
        FREE(a->bounds);
        FREE(a->base_add);
    }
    
    int array_get_value(Array *a, ...)
    {
        va_list va;
        va_start(va, a);
        
        int result = array_get_locate(a, va);
        if(-1 == result) return -1;
        return a->ptr[result];
    }
    
    
    int array_print_line(Array *a)
    {
        int total = 1;
        int i = 0;
        int line ;
        for(; i < a->dim; i++)
        {
            total *= a->bounds[i];
        }
        
        line = total/a->bounds[0];
        for(i = 0; i < total; i++)
        {
            if(0 == i % line && 0 != i) printf("\n");
            printf("%-7d", a->ptr[i]);
        }
        printf("\n");
        return 0;
    }
    
    
    int array_get_locate(Array *a, va_list va)
    {
        int result = 0;
        int bound;
        int i;
        for(i = 0; i < a->dim; i++)
        {
            bound = va_arg(va, int);
            if(0 > bound || bound > a->bounds[i])
            {
                return -1;
            }
            result += bound * a->base_add[i];
        }
        return result;
    }
    
    int array_set_value(Array *a, int value, ...)
    {
        if(NULL == a) return -1;
        va_list va;
        va_start(va, value);
    
        int result = array_get_locate(a, va);
        if( -1 == result) return -1;
    
        a->ptr[result] = value;
        return 0;
    }
    


    blog: http://blog.csdn.net/rentiansheng/article/details/8737225

  • 相关阅读:
    sql总结:
    VS2008生成DLL文件的方法、引用dll文件以及意义
    Mysql日期和时间函数
    删除文件后硬盘可用空间为何不增加?
    C# CheckedListBox控件的用法
    SNMP监控一些常用OID的总结
    解决 MariaDB无密码就可以登录的问题
    Cisco路由器用SSH替代Telnet连接
    思科、华为、H3C常用命令对比大全
    转载:关于思科交换机、路由器如何关闭telnet 开启ssh服务
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2989559.html
Copyright © 2020-2023  润新知