动态申请数组,在C/C++编程之中也算是比较常见的操作,动态申请一维数组相信列位也都能从书中找到,但对于动态申请二维数组,似乎书中甚少提及,不过没关系,看完本文之后我们对于这个操作也就能有个清晰的认识了。下面我们进入正文:
动态申请一维数组的方法很简单,我们都知道数组是一段连续的内存空间,所以只要我们拥有数组首地址,那我们就能对数组元素逐个访问,而数组名有时是被解释为数组首地址(指针)的,基于这个事实,我们就可以得到:
int *p_arr = new int[10]; //如此,我们就成功地动态申请得到了一维数组
//new操作返回数组首地址,用一个指针保存
有了上述的解释,或许有人就会进行以下的操作:
int **p_arr = new int[10][10]; //既然一维数组是一级指针
//那二维数组是否就是二级指针呢?
我们可以编译运行一下,然后我们就能看到问题了,不能将int(*)[]转换为int **。由此,我们就可以引出第一种动态申请二维数组的方法了:
1 #include "iostream" 2 3 using namespace std; 4 5 int main(int argc, char *argv[]) 6 { 7 int (*p_arr)[4] = new int[4][4]; 8 for (int i = 0; i < 4; i++) 9 { 10 for (int j = 0; j < 4; j++) 11 { 12 p_arr[i][j] = i * j; 13 } 14 } 15 16 for (int i = 0; i < 4; i++) 17 { 18 for (int j = 0; j < 4; j++) 19 { 20 cout << p_arr[i][j] << " " << ends; 21 } 22 } 23 24 return 0; 25 }
方括号中的值必须为二维数组第二维的值,虽然可以不是,但这将会引出一个比较麻烦的问题——按索引访问元素是,所得到的或许就不是我们期望的了,这点大家可以自己尝试一番。
下面我们介绍第二种二维数组的动态申请方法,第二种申请方法基于动态一维数组的申请,我们是将动态一维数组转换为二维数组,为何可行?只因为二维数组虽然物理结构像一张二维表一般,但其实实质还是一整段连续的内存空间的,与一维数组一样,所以我们就可以对其进行一定的转换,转换方法如下:
1 #include "iostream" 2 3 using namespace std; 4 5 int main(int argc, char *argv[]) 6 { 7 int nRow, nCol; 8 cin >> nRow >> nCol; 9 int *p_arr = new int[nRow * nCol]; 10 int (*pp_arr)[nCol] = (int(*)[nCol])p_arr; 11 12 for (int i = 0; i < nRow; i++) 13 { 14 for (int j = 0; j < nCol; j++) 15 { 16 pp_arr[i][j] = i * j; 17 } 18 } 19 20 for (int i = 0; i < nRow; i++) 21 { 22 for (int j = 0; j < nCol; j++) 23 { 24 cout << pp_arr[i][j] << " " << ends; 25 } 26 } 27 28 return 0; 29 }
看完上述两种方法,我们就差不多清楚地了解了动态二维数组的申请方式,此外,我们还有一个比较取巧的方式:我们可以先申请一个一维指针数组,然后再对其元素逐个进行申请数组空间,虽然这也可行,但我们并不推荐这样做,理由是,我们不能保证这个数组的连续性!失去了连续性的数组,那我们还不如去使用STL呢。