这是《数据结构、算法与应用 C++语言描述》一书中关于不规则二维数组的示例代码,我在原来的基础上进行了一些修改,以便说说自己对二级指针的理解。
【资料图】
书中的原本的代码仅示例了数组下标操作二维数组的方式,没有对二级指针进行讨论,同时也没有对内存进行释放。当然,原书的本意也只是对不规则二维数组进行演示演示而已。
这里以二级指针的形式,声明了一个二维数组。二级指针既是:指向指针的指针;二维数组既是:一维数组AA中的每个元素都存储一个一维数组。这两个解释,看起来都像在套娃。那为什么不规则二维数组要以二级指针的形式进行声明呢?
在C++中,我们可以声明一个指针,该指针指向一个一维数组。假设有pp,p1,p2,p3四个指针,pp指针指向长度是3的一维数组AA,AA存储了p1,p2,p3。p1指向一维数组A1,p2指向一维数组A2,p3指向一维数组A3。也就是说,实际上AA不存储A1,A2,A3,只是存储了指向A1,A2,A3的指针。
因此,“一维数组AA中的每个元素都存储一个一维数组(A1、A2、A3)”只是表现,实际实现则是“指向指针(p1、p2、p3)的指针(pp)”。因此使用二级指针来申明不规则二维数组。
把这几行代码放一起看看:一维数组AA(new int* [numberOfRows])里的每个元素都是一个一维数组(new int[length[i]])。但要注意到的是AA是int* [ ]类型的,AA里只能放了int * 型的指针。因此要理解irregularArray是指向指针的指针,而不是存着数组的数组。它只是最终表现成存着数组的数组,而不是真的存着数组的数组。这个确实是有点绕。
这段就可以很明显的看出,irregularArray里存的是地址(指针),而这些地址(指针),每个都指向一个一维数组。以下的代码,这是对这些被最终指向的一维数组,进行操作。
在 i 和 j 的嵌套循环中有这种关系:
1、irregularArray[ i ][ j ] 和 *( *( irregularArray + i ) + j ) 是相同意义的。
2、& irregularArray[ i ][ j ] 和 *( irregularArray + i ) + j 是相同意义的。
3、& irregularArray[ i ] 和 irregularArray + i 是相同意义的。
4、 irregularArray即可作为数组名,又可以作为指针。
当irregularArray作为指针时,它指向一维数组 (设该数组为AA) 的首地址,则 irregularArray + i 就是AA的第 i 个元素的地址(上面第3点),而 *( irregularArray + i ) 就是AA的第 i 个元素所保存的地址,这个地址就是另一个一维数组(设该数组为Ai)的首地址,因此 *( irregularArray + i ) + j 就是Ai的第j个元素的地址(上面第2点),因此 *( *( irregularArray + i ) + j ) 就是Ai的第j个元素所保存的数据(上面第1点)。
由于 *( irregularArray + i ) 就是AA的 第i 个元素所保存的地址,这个地址就是另一个一维数组(设该数组为Ai)的首地址。因此delete [ ] *( irregularArray + i )就是释放了最终被指向的所有一维数组的内存空间,最后在delete [ ] irregularArray,释放了存储这些一维数组的指针的空间。
程序结束。
标签: 一维数组