多维数组的顺序表示


多维数组节点,有四个元素
struct array
{
        int *base;            //存放数组的元素的基地址
        int dim;              //表示多维数组的维数
        int *bounds;      //表示每一维的长度
        int *constants;  //存放数组映象函数常量基址

}; 

譬如一个2*3的二维数组,dim就等于二,行优先存储,bounds[0]就为2,bounds[1]就为3。

对于constants,constant[i]就是第i+1层的数组中每一元素(数组)的大小。
对于行主序的2*3的二维数组来说,constant[1]就是每一行的一个元素(如:((a,b,c),(d,e,f))中a,f)占据的内存长度
constant[0]就是当前行每一列(如:(A,B),其中A=(a,b,c),B=(d,e,f)),A、B占据的内存长度。

  1. /* 
  2. 多维数组的顺序表示 
  3. 调试环境:vs2010,gcc 
  4. */ 
  5.  
  6. #include <stdio.h>  
  7. #include <stdarg.h>  
  8. #include <stdlib.h>  
  9. #include <malloc.h>  
  10.  
  11. #define OK      1  
  12. #define ERROR   0  
  13. #define MAX_ARRAY_DIM 8  
  14.  
  15. typedef struct   
  16.     int *base;      //数组的基地址,初始化时分配  
  17.     int dim;            //数组的维数  
  18.     int *bounds;        //数组每一维的长度  
  19.     int *constants; //数组映象函数常量基址  
  20.  
  21. }array; 
  22.  
  23. int init_array(array *a, int dim, ...) 
  24.     int i = 0; 
  25.     int elem_num = 1;       //记录数组中元素的个数  
  26.     va_list ap = NULL; 
  27.  
  28.     if(dim < 1 || dim > MAX_ARRAY_DIM) 
  29.     { 
  30.         return ERROR; 
  31.     } 
  32.     a->dim = dim; 
  33.     a->bounds = (int *)malloc(dim * sizeof(int)); 
  34.     if(!(a->bounds)) 
  35.     { 
  36.         return ERROR; 
  37.     } 
  38.  
  39.     va_start(ap, dim); 
  40.     for(i = 0; i < dim; i++) 
  41.     { 
  42.         a->bounds[i] = va_arg(ap, int); 
  43.         if(a->bounds[i] < 0) 
  44.         { 
  45.             return ERROR; 
  46.         } 
  47.         elem_num *= a->bounds[i]; 
  48.     } 
  49.     va_end(ap); 
  50.  
  51.     a->base = (int *)malloc(elem_num * sizeof(int)); 
  52.     if(! (a->base)) 
  53.     { 
  54.         return ERROR; 
  55.     } 
  56.  
  57.     a->constants = (int *)malloc(dim * sizeof(int)); 
  58.     if(!(a->constants)) 
  59.     { 
  60.         return ERROR; 
  61.     } 
  62.     a->constants[dim - 1] = 1; 
  63.     for(i=dim-2; i>=0; i--) 
  64.     { 
  65.         a->constants[i] = a->constants[i+1] * a->bounds[i+1];   
  66.     } 
  67.  
  68.     return OK; 
  69.  
  70. int destory_array(array *a) 
  71.     if(a->base) 
  72.     { 
  73.         free(a->base); 
  74.         a->base = NULL; 
  75.     } 
  76.     else 
  77.         return ERROR; 
  78.  
  79.     if(a->bounds) 
  80.     { 
  81.         free(a->bounds); 
  82.         a->bounds = NULL; 
  83.     } 
  84.     else 
  85.         return ERROR; 
  86.  
  87.     if(a->constants) 
  88.     { 
  89.         free(a->constants); 
  90.         a->constants = NULL; 
  91.     } 
  92.     else 
  93.         return ERROR; 
  94.  
  95.     return OK; 
  96.  
  97. /*寻找待搜索的arr[i][j][k]相对于基地址的偏移量*/ 
  98. int locate_array_elem(array a, va_list ap, int *offset) 
  99.     int i = 0; 
  100.     int curdim = 0; 
  101.  
  102.     for(i = 0; i < a.dim; i++) 
  103.     { 
  104.         curdim = va_arg(ap, int); 
  105.         if(curdim < 0 || curdim >=a.bounds[i]) 
  106.         { 
  107.             return ERROR; 
  108.         } 
  109.         *offset += a.constants[i] * curdim; 
  110.     } 
  111.  
  112.     return OK; 
  113.  
  114. int get_array_elem(int *e, array a, ...) 
  115.     va_list ap; 
  116.     int result = 0; 
  117.     int offset = 0; 
  118.      
  119.     va_start(ap, a); 
  120.     if(!(result = locate_array_elem(a, ap, &offset))) 
  121.     { 
  122.         return ERROR; 
  123.     } 
  124.     va_end(ap); 
  125.  
  126.     *e = *(a.base + offset); 
  127.  
  128.     return OK; 
  129.  
  130. int assign_array_elem(int e, array *a, ...) 
  131.     va_list ap; 
  132.     int result = 0; 
  133.     int offset = 0; 
  134.     va_start(ap, a); 
  135.     if(!(result = locate_array_elem(*a, ap, &offset))) 
  136.     { 
  137.         return ERROR; 
  138.     } 
  139.     va_end(ap); 
  140.      
  141.     *(a->base + offset) = e; 
  142.  
  143.     return OK; 
  144.  
  145.  
  146. int main(int argc, char *argv[]) 
  147.     array arr; 
  148.     int dim = 3; 
  149.     int bound1 = 2, bound2 = 3, bound3 = 4; //arr[2][3][4]数组  
  150.     int i = 0, j = 0, k = 0; 
  151.     int assign_elem = 0; 
  152.     int get_elem = 0; 
  153.     int *p = NULL; 
  154.  
  155.     init_array(&arr, dim, bound1, bound2, bound3); 
  156.  
  157.     printf("array.bounds = ");          //顺序输出array.bounds  
  158.     p = arr.bounds; 
  159.     for(i = 0; i < dim; i++) 
  160.     { 
  161.         printf("%d ", *(p + i)); 
  162.     } 
  163.  
  164.     printf("\narray.contents = ");      //顺序输出array.contents  
  165.     p = arr.constants; 
  166.     for(i = 0; i < dim; i++) 
  167.     { 
  168.         printf("%d ", *(p + i)); 
  169.     } 
  170.  
  171.     printf("\narray[%d][%d][%d] : \n", bound1, bound2, bound3); 
  172.     for(i = 0; i < bound1; i++) 
  173.     { 
  174.         for(j = 0; j < bound2; j++) 
  175.         { 
  176.             for(k = 0; k < bound3; k++) 
  177.             { 
  178.                 assign_elem = i * 100 + j * 10 + k; 
  179.                 assign_array_elem(assign_elem, &arr, i, j, k); 
  180.                 get_array_elem(&get_elem, arr, i, j, k); 
  181.                 printf("array[%d][%d][%d]=%-4d", i, j, k, get_elem); 
  182.             } 
  183.             printf("\n"); 
  184.         } 
  185.         printf("\n"); 
  186.     } 
  187.  
  188.     p = arr.base; 
  189.     for(i = 0; i < bound1 * bound2 * bound3; i++) 
  190.     { 
  191.         printf("%-4d", *(p + i)); 
  192.         if(i % (bound2 * bound3) == bound2 * bound3 - 1) 
  193.         { 
  194.             printf("\n"); 
  195.         } 
  196.     } 
  197.  
  198.     destory_array(&arr); 
  199.      
  200.     return 0; 

相关内容