我在理解双指针方面有些问题。好吧,我知道这意味着“指针指向指针”。但是,当我在代码中看到它时,我只是不明白。例如:
// Create Dynamic 2D-Array
int **arr = new int*[rows];
for (int i = 0; i < rows; i++)
{
arr[i] = new int[cols];
}
这是我的老师用来创建2D动态数组的代码,但我听不懂。谁能解释?例如int **arr = new int*[rows];
是什么意思?或者我们在那里使用for
是什么?
还有一个问题:是否可以在不使用指针的情况下创建2d动态数组?
答案 0 :(得分:1)
一些发现可能对您有帮助:
指针占用内存的方式与其他任何变量相同。它与任何其他类型相似。因此,如果您为变量i
绘制了一个矩形,则也可以为一个指针绘制一个矩形。
使用typedef
或using
创建别名并简化复杂类型的定义:
using pointer_to_int = int*;
pointer_to_int* arr = new pointer_to_int[rows]; // allocates an array of pointer_to_int (similar to new int[rows])
for (int i = 0; i < rows; i++)
{
arr[i] = new int[cols]; // arr[i] is of type pointer_to_int
}
“有没有不用指针就可以创建2d动态数组的方法?” 这取决于您要查看的级别。最后,会有一个指针。您可以使用一维数组(vector<T>
,如果允许的话)并将其除以行(或列)。如果该行有3列,则第一行从索引0
开始,第二行从索引3
开始,第三行从索引6
开始,依此类推。请参见 { {3}} 。
答案 1 :(得分:1)
从90年代到2011年(以及之后的一段时期)编写的代码中,您会看到很多这种类型的代码。允许使用2D数组索引访问元素的这种指针集合已由std::vector
(或本例中的向量)代替。
首先要了解的是int **arr;
向 pointer-to-int 声明一个单指针。 (也称为双指针)。无论哪种方式,您都有单指针到什么位置? (指向类型的指针,无论使用的type
是什么。)
为了使该方法有用,您首先分配所需的 pointers 数量。以下内容分配了一个内存块,其中包含rows
个 pointer-to-int 指针,并将第一个指针的地址分配给arr
。
int **arr = new int*[rows];
现在您有rows
个未初始化指针。 (例如,您有一块能够容纳rows
指针的内存)。要访问arr
中的每个指针,您只需使用数组索引(例如arr[2]
是分配的块中的3 rd 指针。)等效的指针符号为{{1 }}。 (注意:,*(arr + 2)
的取消引用与指针表示法中的[..]
相同)
要有用,分配的块中的每个指针必须指向保存一定数量整数的有效内存。您可以为现有的整数数组分配地址,例如
*(..)
在您的情况下,您只是在分配一个可以包含#define COLS 5
...
int myarray[COLS] = {0}; /* array of COLS integer values initialized zero */
int **arr = new int*[rows]; /* your allocation a block for rows pointers to int */
...
arr[0] = myarray; /* assigning pointer to existing block to arr[0] */
个整数的内存块,并将该块的起始地址分配给用cols
分配的块中的指针之一。这就是以下代码的作用:
int **arr = new int*[rows];
现在您的对象已完成。您有一块内存大小,因此它可以包含// Create rows pointers pointing to allocated blocks of cols integers
int **arr = new int*[rows]; /* allocated block of rows pointers */
for (int i = 0; i < rows; i++) /* for each pointer */
{
arr[i] = new int[cols]; /* allocate & assign block of cols int */
}
个指针,并且您已经分配了rows
个可以容纳rows
个整数的内存块,并分配了起始地址。每个内存块的地址,其中cols
包含整数个指向分配给原始块中每个指针的整数。
由于您可以使用cols
访问每个指针,其中arr[x]
,因此只需包含另一个索引(模拟的2D索引),您就可以访问每个内存块中的每个整数,这样{{1} }将寻址由0 <= x < rows
指向arr[x][y]
指向的内存块中的y 整数。等效的指针符号为arr[x]
。
就是这样。您为一定数量的指针分配存储空间,然后为一定数量的0 <= y < cols
值分配存储空间,并为每个指针分配起始地址,以便每个指针现在都拥有(例如指向)一个指针的地址。分配的内存块保存您的值。
现在,您必须分别*(*(arr + x) + y)
个type
个整数的每个存储块(例如循环和delete[]
),然后最后一次调用cols
释放包含指针的内存块。
仔细考虑,如果还有其他问题,请告诉我。
答案 2 :(得分:0)
它创建一个指针数组,该数组中的每个指针指向内存中的不同位置
+-arr--+
| | +---------------+
| 0 | -> | ... cols |
| | +---------------+
+------+
| | +---------------+
| 1 | -> | ... cols |
| | +---------------+
+------+
...
+------+
| | +---------------+
|rows-1| -> | ... cols |
| | +---------------+
+------+
因此它不包含连续的内存,就像您将其声明为
一样int arr[rows][cols];