开辟二维数组

动态分配二维数组的若干方法      
     
    动态分配二维数组,方法很多,在这里我说一下我想到的。针对二维数组两      
  个维的不同,可用不同的方法处理。      
     
  一、两维都固定:      
     
    这种是最简单,如下:      
     
        //     有点困惑的方法:      
        int     (*a)[M][N];                                                     //     M、N     为常量      
        a     =     new     int[1][10][20];                     //     为什么要这样呢?      
        delete[]     a;      
     
        //     typedef     法,但一样的困惑      
        typedef     int     array_two[10][20];      
        array_two*     a     =     new     array_two[1];     //     还是多了“一维”      
        delete[]     a;      
     
    唉,这个有点失败,使用时还要这样:(*a)[m][n],或者     a[0][m][n],这      
  还是二维的吗?没办法,只有另想办法了。      
     
        //     退一步,声明似乎少了一维         TYPE_1      
        int     (*a)[N];      
        a     =     new     int[M][N];      
        a[var_m][var_n]     =     0;      
        delete[]     a;      
     
    这样似乎不错,只是在声明时却少了一维,但使用起来简单,形式一样。      
     
  二、只有一维固定:      
     
    如果只有一维固定,分两种形式:[M][n]     和     [m][N],以后者较简单。对于          
  N     固定的,我们只要这样就可以了:      
     
        //     [m][N]     型                                                                 TYPE_2      
        int     (*a)[N];      
        a     =     new     int[m][N];      
        a[var_m][var_n]     =     0;      
        delete[]     a;      
     
    这个看起来与     TYPE_1     很相似,比较二维数组作为函数的参数传递时,第一      
  维也是不重要的。看一下     new,出来的类型都是     int     (*)[N]。      
     
    对于     [M][n]     这种,能过把下标交换一下,就可以利用     TYPE_2     这种了,确      
  实是不错。如果坚持用     [M][n]     的话,看一下有什么方法。      
     
        //     [M][n]     型,直接的方法                 TYPE_3      
        int*     a[M];      
        for     (int     i     =     0;     i     <     M;     ++i)      
                a[i]     =     new     int[n];      
        a[var_m][var_n]     =     0;      
        for     (int     i     =     M;     i     >     0;)      
                delete[]     a[--i];      
     
    事实上,我们可以改进一下,只用一次     new:      
     
        //     [M][n]     型,改进                                                         TYPE_4      
        int*     a[M];      
        a[0]     =     new     int[M*n];      
        for     (int     i     =     1;     i     <     M;     ++i)      
                a[i]     =     a[i-1]     +     n;      
        a[var_m][var_n];      
        delete[]     a[0];      
     
    这样改进的好处是,减少     new     所带来的固有开销;如果失败,无需对前面      
  已分配的再     delete[]。当然,如果内存比较碎的话,那就没办法了。      
     
  三、二维都是动态确定:      
     
    二维都是动态确定的话,可以这样:      
     
        //     [m][n],直接的方法                                             TYPE_5      
        int**     a;      
        a     =     new     (int*)[m];      
        for     (int     i     =     0;     i     <     m;     ++i)      
                a[i]     =     new     int[n];      
        a[var_m][var_n]     =     0;      
        for     (int     i     =     m;     i     >     0;)      
                delete[]     a[--i];      
        delete[]     a;      
     
    类似改进     TYPE_3,我们也可以将     TYPE_5     改进:      
     
        //     [m][n],改进                                                                     TYPE_6      
        int**     a;      
        a     =     new     (int*)[m];      
        a[0]     =     new     int[m*n];      
        for     (int     i     =     1;     i     <     m;     ++i)      
                a[i]     =     a[i-1]     +     n;      
        a[var_m][var_n]     =     0;      
        delete[]     a[0];      
        delete[]     a;      
     
    好了,这就是我所想到的办法,当然你可以     std::vector     来搭建二维数组,      
  只是效率似乎没人满意。实际上,可以只分两种情况:最后一维确定,或不确定。      
  最后一维确定,只需一次分配;否则,一般要两次。      
  ---------------------------------------------------------------      
     
  //     [M][n]     型,改进                                                         TYPE_4      
        int*     a[M];      
        a[0]     =     new     int[M*n];      
        for     (int     i     =     1;     i     <     M;     ++i)      
                a[i]     =     a[i-1]     +     n;      
        a[var_m][var_n];      
        delete[]     a[0];      
  这里似乎有些问题,是不是应该改成a[i]     =     a[i-1]     +     sizeof(int)*n;      
  ---------------------------------------------------------------      
     
  有价值。      
  up      
  ---------------------------------------------------------------      
     
  up      
  ---------------------------------------------------------------      
     
  int     (*a)[M][N];                                                     //     M、N     为常量      
  a     =     new     int[1][10][20];                     //     为什么要这样呢?      
     
  这里的a不应该是一个三维数组吗?不知道是楼主弄错了还是我理解得不对?      
  另外,用vector来构建二维数组我觉得没有什么不好,不知道为什么楼主认为效率不令人满意?      
  ---------------------------------------------------------------      
     
  楼上的意见我认可      
  *a[][]逻辑上已经是三维了      
     
  至于你的typedef     int     array_two[10][20];      
        array_two*     a     =     new     array_two[1];     //     还是多了“一维”      
  这样定义了     array_two本身是二维数组,定义它的指针也应该是首先分配的是二维数组指针的空间          
         
  typedef     定义对象指针      
  有一个好处就是new的时候不会调用构造函数      
     
  class     Object{...      
  }      
     
  typedef     Object*     OFun[1];      
  OFun     =     new     Object[1];      
  ---------------------------------------------------------------      
     
  学习...      
  ---------------------------------------------------------------      
     
  mark      
  ---------------------------------------------------------------      
     
  int     (*a)[M][N];                                                     //     M、N     为常量      
  a     =     new     int[1][10][20];                     //     为什么要这样呢?      
     
  逻辑上是三维了,感觉就是用起来会方便一点吧,是作为指针来用了,作为一个二维指针,不过自己还没用到过这么困难的东西,看了是不少书,理论也不少了,可还是没实践,学习,      
  ---------------------------------------------------------------      
     
  还有,我最推荐的是TYPE_5,这个东西可以搭建的就不只是m*n的数组了,而是一堆大小不同的一维数组的集合  

转载于:https://www.cnblogs.com/anderson0/archive/2009/04/03/1429223.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值