C++中二维数组new小结

本文探讨了六种不同的动态内存分配方式,包括使用数组、指针及STL容器等方法,并对比了它们的优点和缺点。重点介绍了这些方法在不同场景下的适用性和效率。
1. 
A (*ga)[n] = new A[m][n]; 
... 
delete []ga; 
缺点:n必须是已知 
优点:调用直观,连续储存,程序简洁(经过测试,析构函数能正确调用) 

2. A** ga = new A*[m]; 
for(int i = 0; i < m; i++) 
ga[i] = new A[n]; 
... 
for(int i = 0; i < m; i++) 
delete []ga[i]; 
delete []ga; 
缺点:非连续储存,程序烦琐,ga为A**类型 
优点:调用直观,n可以不是已知 

3. A* ga = new A[m*n]; 
... 
delete []ga; 
缺点:调用不够直观 
优点:连续储存,n可以不是已知 

4. vector <ga>; 
ga.resize(m); //这三行可用可不用 
for(int i = 1; i < n; i++) // 
ga[i].resize(n); // 
... 

缺点:非连续储存,调试不够方便,编译速度下降,程序膨胀(实际速度差别不大) 
优点:调用直观,自动析构与释放内存,可以调用stl相关函数,动态增长 

5. vector ga; 
ga.resize(m*n); 
方法3,4的结合 


6. 2的改进版
A** ga = new A*[m]; 
ga[0] = new A[m*n]; 
for(int i = 1; i < m; i++) 
ga[i] = ga[i-1]+n; 
优点:连续存储,n可以不是已知,析构方便,猜想只需delete [] ga;
<think>我们正在讨论C++中二数组指针的表示方法。根据提供的引用,我们可以总结几种常见的表示方式: 1. **指向数组的指针**:这种形式通常用于静态大小的二数组。例如,对于一个3列的二数组,可以声明为 `int (*p)[3]`,然后将其指向二数组的首地址(如 `p = arr;`)。这样,`p` 就是一个指向含有3个整数的数组的指针。 2. **指针的指针(二级指针)**:这种形式常用于动态分配的二数组。首先分配一个指针数组,然后为每一行分配内存。例如: ```cpp int** array = new int*[rows]; for (int i = 0; i < rows; i++) { array[i] = new int[cols]; } ``` 然后,可以将这个二级指针传递给函数。 3. **在函数参数中使用固定列数的数组指针**:在函数参数中,我们可以这样写来表示一个二数组(列数固定): ```cpp void func(int arr[][3], int rows); ``` 实际上,这里`arr`的类型就是指向含有3个整数的数组的指针(即`int (*)[3]`)。 4. **使用一级指针模拟二数组**:将二数组按行展开成一数组,然后通过计算索引来访问元素。例如,传递一个一级指针和行列数: ```cpp void func(int* arr, int rows, int cols) { // 访问arr[i][j] 可以用 arr[i*cols+j] } ``` 5. **使用数组指针的数组**:如引用[5]中提到的,可以定义一个数组,其元素是指向一数组的指针(即数组指针)。例如: ```cpp int ia[3][4]; // 假设有3行4列的二数组 int (*iapa[3])[4] = {&ia[0], &ia[1], &ia[2]}; // iapa是一个数组,包含3个指向含4个int的数组的指针 int i = (*iapa[2])[2]; // 相当于ia[2][2] ``` 根据用户需求“查找C++中二数组指针的表示方法”,我们重点介绍最常用的前两种:指向数组的指针(用于静态数组)和二级指针(用于动态数组)。 ### 1. 指向数组的指针(静态二数组) 对于一个静态定义的二数组,如: ```cpp int arr[3][4]; ``` 我们可以定义一个指向该数组第一行的指针: ```cpp int (*p)[4] = arr; // p指向arr的第一行 ``` 这样,通过`p`可以访问整个二数组: ```cpp for (int i=0; i<3; i++) { for (int j=0; j<4; j++) { cout << p[i][j] << " "; // 或者 *(*(p+i)+j) } cout << endl; } ``` ### 2. 二级指针(动态二数组) 动态分配二数组: ```cpp int rows = 3, cols = 4; int** dp = new int*[rows]; // dp指向一个指针数组的首元素 for (int i=0; i<rows; i++) { dp[i] = new int[cols]; // 每个指针指向一行 } ``` 然后,我们可以通过`dp[i][j]`来访问元素。 ### 在函数参数中传递二数组指针 - 对于静态数组(列数固定),函数参数可以声明为指向数组的指针: ```cpp void func(int (*p)[4], int rows); // 或者等价的 void func(int p[][4], int rows); ``` - 对于动态数组(二级指针),函数参数声明为二级指针: ```cpp void func(int** dp, int rows, int cols); ``` ### 示例代码 下面给出两个示例: #### 示例1:静态二数组指针 ```cpp #include <iostream> using namespace std; void printStaticArray(int (*arr)[4], int rows) { for (int i=0; i<rows; i++) { for (int j=0; j<4; j++) { cout << arr[i][j] << " "; } cout << endl; } } int main() { int a[2][4] = {{1,2,3,4}, {5,6,7,8}}; printStaticArray(a, 2); return 0; } ``` #### 示例2:动态二数组指针 ```cpp #include <iostream> using namespace std; void printDynamicArray(int** arr, int rows, int cols) { for (int i=0; i<rows; i++) { for (int j=0; j<cols; j++) { cout << arr[i][j] << " "; } cout << endl; } } int main() { int rows = 2, cols = 3; int** array = new int*[rows]; for (int i=0; i<rows; i++) { array[i] = new int[cols]; for (int j=0; j<cols; j++) { array[i][j] = i*cols + j + 1; } } printDynamicArray(array, rows, cols); // 释放内存 for (int i=0; i<rows; i++) { delete[] array[i]; } delete[] array; return 0; } ``` ### 注意事项 - 静态二数组的列数必须在编译时确定,因此函数参数中必须指定列数。 - 动态二数组通过二级指针传递,需要同时传递行数和列数。 - 避免混用这两种类型(例如,不要将静态二数组名直接传给二级指针参数)。 以上是C++中二数组指针的主要表示方法。用户可以根据实际场景(静态数组还是动态分配)选择合适的方式。 §§相关问题§§ 1. C++中二数组作为函数参数传递有哪些方式? 2. 如何动态分配和释放二数组内存? 3. 为什么不能直接将静态二数组名赋值给二级指针? 4. C++中如何避免二数组传递时的内存错误? </think>### C++中二数组指针的表示方法 在C++中,二数组指针主要有以下几种表示方式,根据应用场景和数组类型(静态/动态)有所不同: --- #### 1. **指向固定列宽的二数组(静态数组)** 当二数组列数固定时,使用**数组指针**语法: ```cpp int arr[3][4]; // 定义3行4列的二数组 int (*p)[4] = arr; // p是指向含4个元素的整型数组的指针 ``` - `(*p)[4]` 表示 p 是指向长度为4的整型数组的指针 - 访问元素:`p[i][j]` 或 `*(*(p+i)+j)` **示例用法**: ```cpp void printArray(int (*arr)[4], int rows) { for(int i=0; i<rows; i++) { for(int j=0; j<4; j++) cout << arr[i][j] << " "; cout << endl; } } // 调用: printArray(arr, 3); ``` --- #### 2. **二级指针表示法(动态数组)** 适用于动态分配的二数组: ```cpp int rows = 3, cols = 4; int** dp = new int*[rows]; // 分配行指针数组 for(int i=0; i<rows; i++) dp[i] = new int[cols]; // 为每行分配空间 ``` - `dp` 是指向指针的指针(`int**`) - 访问元素:`dp[i][j]` **函数参数传递**: ```cpp void process(int** arr, int rows, int cols) { for(int i=0; i<rows; i++) for(int j=0; j<cols; j++) arr[i][j] = i*j; } ``` --- #### 3. **一指针模拟二数组** 将二数组视为连续内存块: ```cpp int arr[3][4]; int* p = &arr[0][0]; // 指向首元素的指针 // 访问arr[i][j]: p[i*4 + j] ``` **函数参数传递**: ```cpp void func(int* arr, int rows, int cols) { // 访问[i][j]: arr[i*cols + j] } ``` --- #### 4. **指针数组转换(适配二级指针函数)** 当需要将静态二数组传给接受`int**`的函数时: ```cpp int arr[3][4]; int* p_arr[3] = {arr[0], arr[1], arr[2]}; // 创建指针数组 // 调用二级指针函数 process(p_arr, 3, 4); // ✅ 正确传递 ``` --- ### 关键区别总结 | **类型** | **声明方式** | **适用场景** | **内存布局** | |------------------|-------------------|-------------------|-----------------| | 静态固定列宽 | `int (*p)[N]` | 编译期已知列数 | 连续内存块 | | 动态数组 | `int** dp` | 运行时决定行列数 | 非连续内存 | | 一指针模拟 | `int* p` | 连续内存操作 | 连续内存块 | | 指针数组转换 | `int* pa[]` | 适配二级指针接口 | 混合布局 | > ⚠️ **重要注意事项**: > 1. 静态二数组名 `arr` 的类型是 `int(*)[N]` (数组指针),不是 `int**` > 2. 直接传递 `arr` 给 `int**` 参数会导致类型不匹配错误 > 3. 动态分配的二数组必须显式释放内存: > ```cpp > for(int i=0; i<rows; i++) delete[] dp[i]; > delete[] dp; > ``` [^1][^2][^3][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值