通过knr,我已经达到了多维数组。
我想知道几件事:
第一。
假设我初始化以下数组
int a[2][4] = {{1,2,3},{4,5,6}};
现在,我将其理解为留出 2 个块 4*sizeof(int( 字节的连续内存。好吧,那么在我看来,这只是一种将内存乘法定义的好方法放在一边。所以。。。为什么以下情况不正确:
int a[8] == int[2][4]
第二,当我走的时候,
int a[2][3] = {{1,2,3},{2,3,4}};
为什么此尝试失败
a[5] = 22;
那么,如果多维数组不仅仅是一个连续的内存块,那么它是什么?
如果你有 int a[2][4] 并且你尝试访问 a[1],则 a[1] 是一个 int[] 而不是 int。
换句话说,a[1] 是一个数组,而 a[1][1] 是一个整数值。
你需要投射才能做你想做的事。
T a[x][y][z];
a
是 T
类型的数组(每个有 y
个元素(的数组(每个有 z
个元素(的数组(x
个元素(。
更新:
如上所述定义的数组确实是一个连续的内存块。
然而看到这样的线
T t = b[0][0[0];
不知道a
是如何定义的并不一定意味着b
是一个连续的内存块,其中包含可通过 3 维索引b
访问的所有元素。
数组可以分散。
例如
T ** c1 = malloc(x * sizeof(*c1));
for (size_t i = 0; i < x; ++i)
c1[i] = malloc(y * sizeof(**c1));
将允许您以与访问完全相同的方式访问c1
的x
* y
元素
T c2[x][y];
c2
元素存储在一个连续的内存区域中,而c1
元素分散在大小为y
的x
区域中,与c2
的大小相比,c1
大小的额外内存块x * sizeof(*c1)
。
多维数组只是一个连续的内存块。 但是,当您声明一个变量时,编译器希望您按照声明的变量使用该变量。因此,如果您将a
声明为带有以下行的二维数组
int a[2][4] = {{1,2,3},{4,5,6}};
然后编译器将变量a
视为二维数组。
如果你想以一维数组的形式访问该数组,那么你需要声明另一个变量,例如
int *b = (int *)a;
然后你可以用这样的代码访问数组的元素
for ( i = 0; i < 8; i++ )
printf( "%d %dn", i, b[i] );
输出将是
0 1
1 2
2 3
3 0
4 4
5 5
6 6
7 0
请注意位置 3 和 7 处的零。 这些元素为零,因为数组的每一行都声明为包含 4 个项目,但初始值设定项每行只有 3 个项目。初始值设定项中的任何未指定项都用零填充。