加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

一个例子弄明白C语言动态多维数组的创建,存储,引用及降维操作;

(2013-03-21 02:19:03)
标签:

c语言

it

分类: 010101
在C语言编写过程中,最麻烦的莫过于对数组的操作,通用编程可能还感觉不到,像我这种做科学计算经常要处理高维数组,刚开始的编程时候简直是个悲剧。C语言函数还不支持直接传递高维数组,一度很打击我对这种高效的语言的兴趣。
 
在网上搜了一些例子,也看了一些书,发现很多人都不推荐使用高维数组((╯‵□′)╯︵┻━┻),个别的讲到的,也一直在讲理论,(“一个二维指针数组中的指针指向二维数组print出来结果是什么”(╯‵□′)╯︵┻━┻口胡谁想知道这个啊!)。
 
在这里我用一个例子简单展示高维数组的常见操作,我给的例子是三维的,实际上可以类推到更高维度。
 
对于我而言经常需要进行的操作是:
 
1)创建可变高维数组;
 
2)传递高维数组;
 
3)降维,输出高维数组中低维度的一部分;
 
这几个操作在这个例子里都能清晰地看见。
 
# include <stdio.h>

void print3Dmatrix(int ***D3_num,int n,int m, int l) //以***D3_num形式将D3_num的首地址传入
{
    int i,ii,iii;
    printf("\n3D matrix is: \n");
    for (i=0;i<</font>n;i++){
        printf("[]\n",i);
        for (ii=0;ii<</font>m;ii++){

            for (iii=0;iii<</font>l;iii++){
                printf("%.3d ",D3_num[i][ii][iii]);
            }
            printf("\n");
        }
    }
}

int **D3ToD2(int ***D3_num) //int **表示返回的是一个二级指针
{
    int **D2_num;
    D2_num=D3_num[0];//D3_num是一个三级指针,D3num[0]是一个二级指针,D3num[0][0]是一个一级指针
    return D2_num;
}

void print2Dmatrix(int **D2_num,int m, int l)
{
    int ii,iii;
        printf("\n2D matrix is:\n");
        for (ii=0;ii<</font>m;ii++){

            for (iii=0;iii<</font>l;iii++){
                printf("%.3d ",D2_num[ii][iii]);
            }
            printf("\n");
        }

}

int main()
{
    int i,ii,iii;//初始化参数
    int n=2,m=3,l=4; //三维数组长度

    int ***D3_num;    //声明一个三级指针
    D3_num=(int***)malloc(n*sizeof(int**));    //分配空间,该三级指针指向n个二级指针
    for (i=0;i<</font>n;i++){
        D3_num[i]=(int**)malloc(m*sizeof(int*));//分配空间,每个二级指针又指向m个一级指针
        for (ii=0;ii<</font>m;ii++){
            D3_num[i][ii]=(int*)malloc(l*sizeof(int));//分配空间,每个一级指针指向长度为l的一维数组
            for (iii=0;iii<</font>l;iii++){
                D3_num[i][ii][iii]=(i+1)*(ii+2)*(iii+3);//为每个数组赋值,这里D3_num[i][ii][iii]的形式与我们平常用三维数组的形式一致
                //但实际D3_num[i][ii][iii]是一种简写,C编译器解释起来是 *(*(*(p+i)+ii)+iii),所以可以直接赋值
                       
        }
    }

    print3Dmatrix(D3_num,n,m,l);//输出D3_num内容,这里直接将D3_num作为三级指针输入

    int **D2_num; //三级指针可以表示三维数组,二级指针自然就表示二维数组了:D
    D2_num=D3ToD2(D3_num);//D3ToD2返回一个二级指针,与D2_num匹配

    print2Dmatrix(D2_num,m,l);
    getchar();
    return 0;
}
 
另外关于高维数组的存储也有需要注意的。
 
以三维数组为例,可以把它想象成为一个三维空间,维度为xyz。一般比较直观的存法,比如我在matlab里经常是这样存:
D3Matrix(x,y,z);
 
如果需要当z=1时候的二维矩阵直接调用
D3Matrix(:,:,1);
 
但是对于C来讲,这样做是不行的。C的高维数组本质上还是一维数组,只不过给分段了,而存储的变化顺序是越往右边的维度变化越快,左边的维度其实都相当于是指定起始地址。所以在C里,如果你以
D3Matrix[x][y][z]
存储了三维数组,你想单独拿出z=1时候的D3Matrix[x][y]是非常麻烦的。
 
所以正常情况,高维度应该反倒往左边放。类似这样的形式:
D3Matrix[z][y][x]
 
当想返回z=1时候的二维数组,就用一个二维指针去指向
D3Matrix[1]
就可以了。这样做很方便,也非常直观,这也是为什么我采用多级指针来存储高维数组的原因。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有