2012-04-29 18:16 【转】C++动态开辟二维数组

动态分配二维数组的若干方法

  动态分配二维数组,方法很多,在这里我说一下我想到的。针对二维数组两
个维的不同,可用不同的方法处理。

一、两维都固定:

  这种是最简单,如下:

// 有点困惑的方法:
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的数组了,而是一堆大小不同的一维数组的集合 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值