对于我的任务,我在程序中要做的一件事就是动态分配一个2D数组。 我无法弄清楚如何做或为什么。
这就是我现在所拥有的。
size = atoi(argv[1]);
int Pond[size][size];
int i, j;
for(i = 0; i < size; i ++){
for(j = 0; j < size; j++){
Pond[i][j]=0;
}
}
我找到了这样做的答案,但我无法弄清楚如何访问每一列或每行。
int **Pond;
Pond = (int**)malloc(size * sizeof(int*));
for (i = 0; i < size; i++) {
Pond[i] = (int *) malloc(size * sizeof(int));
答案 0 :(得分:4)
正确使用C&#39的强大数组类型语法如下所示:
int (*Pond)[size] = malloc(size * sizeof(*Pond));
这是分配的原因。之后,Pond
中的元素可以像这样访问:
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
Pond[y][x] = 0;
}
}
当然还有释放:
free(Pond);
它并不简单。
答案 1 :(得分:2)
[]
运算符对指针的处理方式与对数组表达式的处理方式非常相似,因此无论您如何分配,都要使用Pond[i][j]
来访问特定元素(除非您已分配)它作为一维数组,如dom0所示。)
如果在编译时已知行数和列数,则这是最简单的:
#define M ... // rows
#define N ... // columns
int (*Pond)[N] = malloc ( sizeof *Pond * M);
...
Pond[i][j] = x;
...
free( Pond );
变量Pond
的类型是&#34;指向N
的指针 - int
&#34;的元素数组。 表达式 *Pond
的类型是&#34; int
&#34;的N元素数组。所以sizeof *Pond
给出了N
中int
的元素数组中的字节数;我们将其乘以M
以获得数组所需的总字节数。
由于a[i]
被评估为*(a + i)
,因此[]
运算符在指针表达式上的工作方式与在数组表达式 1 上的工作方式相同;也就是说,您可以像使用常规2D数组一样使用Pond[i][j]
。
如果直到运行时才知道行数和列数,但您使用的是C99编译器或支持可变长度数组的C2011编译器,那么它很漂亮大致相同:
size_t n, m;
/**
* get values of n and m
*/
int (*Pond)[n] = malloc( sizeof *Pond * m );
...
Pond[i][j] = x;
...
free( Pond );
与上述相同,只是m
和n
在运行时才知道。在这两种情况下,动态分配的数组都是连续的(所有行在内存中都相邻)。
+---+
Pond: | | ---+
+---+ |
... |
+---+ |
Pond[0][0]: | | <--+
+---+
Pond[0][1]: | |
+---+
...
+---+
Pond[0][n-1]: | |
+---+
Pond[1][0]: | |
+---+
Pond[1][1]: | |
+---+
...
+---+
Pond[m-1][0]: | |
+---+
Pond[m-1][1]: | |
+---+
...
+---+
Pond[m-1][n-1]: | |
+---+
如果直到运行时才知道行数和列数,并且您使用的是不支持VLA的编译器,则根据您是否希望数组是连续的,您有两种选择。
如果阵列不必连续,您可以使用两步分配方法:
size_t n, m;
/**
* get values for n and m
*/
int **Pond = malloc( sizeof *Pond * m ); // allocate m rows of pointer to int
if ( Pond )
{
for ( size_t i = 0; i < m; i++ )
{
Pond[i] = malloc( sizeof *Pond[i] * n ); // allocate n columns of int for each row
}
}
在这种情况下,Pond
是指向int
的指针;它最终会指向int
的一维指针数组;这些指针中的每一个都将指向int
的一维数组,类似于以下内容:
+---+
Pond: | | ---+
+---+ |
|
+------+
|
V
+---+
Pond[0]: | | ------------+
+---+ |
Pond[1]: | | ---------+ |
+---+ | |
Pond[2]: | | | |
+---+ | |
... | |
+---+ | |
Pond[m-1]: | | | |
+---+ | |
| |
+---+ | |
Pond[0][0]: | | <--------|--+
+---+ |
Pond[0][1]: | | |
+---+ |
... |
+---+ |
Pond[0][n-1]: | | |
+---+ |
|
+---+ |
Pond[1][0]: | | <--------+
+---+
Pond[1][1]: | |
+---+
...
+---+
Pond[1][n-1]: | |
+---+
但是因为Pond[i][j]
被评估为*(*(Pond + i) + j)
,所以它仍然有效。
请注意,由于这是一个两步分配过程,因此重新分配还需要两个步骤:
for ( size_t i = 0; i < m; i++ )
free( Pond[i] );
free( Pond );
如果数组确实需要连续,那么您必须将内存分配为一维数组并手动计算索引:
int *Pond = malloc( sizeof *Pond * m * n );
...
Pond[ i * m + j ] = x;
...
free( Pond );
<小时/> 1。在大多数情况下,数组表达式将被转换或&#34;衰减&#34;到指针表达式,所以下标实际上是在指针表达式上工作。