让我们从头开始。
动态分配T 的 N 元素数组(对于一些任意的T)的典型方法是
T *p = malloc( sizeof *p * N ); // sizeof *p == sizeof (T)
这为T类型的N个对象分配了足够的空间,p指向第一个元素
T * T
+–––+ +–––+
p: | |–––––>| | p[0]
+–––+ +–––+
| | p[1]
+–––+
...
+–––+
| | p[N-1]
+–––+
现在,将 T 替换为数组类型 - R [M]:
R (*p)[M] = malloc( sizeof *p * N );
这为 R [M] 类型的 N 个对象分配了足够的空间 - IOW 你已经分配了一个 R 的 NxM 数组。 p 仍然指向第一个元素,只是在这种情况下,第一个元素本身就是一个数组。
R (*)[M] R [M]
+–––+ +–––+
p: | |––––––>| | p[0][0]
+–––+ + - +
| | p[0][1]
+ - +
...
+ – +
| | p[0][M-1]
+––—+
| | p[1][0]
+ – +
| | p[1][1]
+ - +
...
+ – +
| | p[1][M-1]
+–––+
...
+ – +
| | p[N-1][M-1]
+–––+
您可以像任何常规二维数组一样索引到 p。
您可以将其扩展到更高维度的数组 - 将 R 替换为另一种数组类型,例如 Q [L]:
Q (*p)[M][L] = malloc( sizeof *p * N );
这会为 NxMxL 数组分配空间,并且您可以再次像任何 3d 数组 p[i][j][k] 一样对其进行索引。
语义在每种情况下都完全相同 - 您为 N 个对象分配空间,只是对象的类型不同。