rob*_*ntw 38 c arrays low-level
我知道C中的数组是按行主顺序分配的.因此,对于2 x 3阵列:
0 1
2 3
4 5
Run Code Online (Sandbox Code Playgroud)
存储在内存中
0 1 2 3 4 5
Run Code Online (Sandbox Code Playgroud)
但是,如果我有一个2 x 3 x 2阵列怎么办:
0 1
2 3
4 5
Run Code Online (Sandbox Code Playgroud)
和
6 7
8 9
10 11
Run Code Online (Sandbox Code Playgroud)
这些如何存储在内存中?只是连续像:
0 1 2 3 4 5 6 7 8 9 10 11
Run Code Online (Sandbox Code Playgroud)
或者是其他方式?还是取决于什么?
aro*_*oth 26
在较低的层次上,没有多维数组这样的东西.只有一个平坦的内存块,大到足以容纳给定数量的元素.在C中,多维数组在概念上是一个数组,其元素也是数组.所以,如果你这样做:
int array[2][3];
Run Code Online (Sandbox Code Playgroud)
从概念上讲,你最终得到:
array[0] => [0, 1, 2]
array[1] => [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)
这导致元素在存储器中连续排列,因为实际上array[0]
并array[1]
没有保存任何数据,它们只是对两个内部数组的引用.请注意,这意味着只有[0, 1, 2]
条目实际占用内存空间.如果将此模式扩展到下一个维度,您可以看到:
int array[2][3][2];
Run Code Online (Sandbox Code Playgroud)
...会给你一个像这样的结构:
array[0] => [0] => [0, 1]
[1] => [0, 1]
[2] => [0, 1]
array[1] => [0] => [0, 1]
[1] => [0, 1]
[2] => [0, 1]
Run Code Online (Sandbox Code Playgroud)
继续在内存中连续排列元素(如上所述,只有[0, 1]
条目实际占用内存中的空间,其他所有内容只是对其中一个条目的引用的一部分).如您所见,无论您拥有多少维度,此模式都将继续.
而且只是为了好玩:
int array[2][3][2][5];
Run Code Online (Sandbox Code Playgroud)
给你:
array[0] => [0] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
[1] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
[2] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
array[1] => [0] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
[1] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
[2] => [0] => [0, 1, 2, 3, 4]
[1] => [0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
pmg*_*pmg 18
所有"尺寸"都连续存储在存储器中.
考虑
int arr[4][100][20];
Run Code Online (Sandbox Code Playgroud)
你可以说,arr[1]
和arr[2]
(类型int[100][20]
)是连续的
,或者arr[1][42]
和arr[1][43]
(类型int[20]
)是连续的
,或者arr[1][42][7]
和arr[1][42][8]
(类型int
)是连续
sje*_*397 13
是的,你是对的 - 它们是连续存储的.考虑这个例子:
#include <stdio.h>
int array3d[2][3][2] = {
{{0, 1}, {2, 3}, {3, 4}},
{{5, 6}, {7, 8}, {9, 10}}
};
int main()
{
int i;
for(i = 0; i < 12; i++) {
printf("%d ", *((int*)array3d + i));
}
printf("\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0 1 2 3 3 4 5 6 7 8 9 10
是的,它们只是按顺序存储.您可以像这样测试:
#include <stdio.h>
int main (int argc, char const *argv[])
{
int numbers [2][3][4] = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
,{{13,14,15,16},{17,18,19,20},{21,22,23,24}}};
int i,j,k;
printf("3D:\n");
for(i=0;i<2;++i)
for(j=0;j<3;++j)
for(k=0;k<4;++k)
printf("%i ", numbers[i][j][k]);
printf("\n\n1D:\n");
for(i=0;i<24;++i)
printf("%i ", *((int*)numbers+i));
printf("\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这意味着对具有维度(N,M,L)的多索引数组的访问将转换为ondimensional访问,如下所示:
array[i][j][k] = array[M*L*i + L*j + k]
Run Code Online (Sandbox Code Playgroud)
我想你已回答了自己的问题.多维数组以行主顺序存储.
请参阅ANSI C规范第3.3.2.1节(还有一个具体示例):
连续的下标运算符指定多维数组对象的成员.如果E是具有维度ixj"x ... x"k的n维数组(n = 2),则E(用作除左值之外的值)被转换为指向(n-1)维数组的指针尺寸为j"x ... x"k.如果将unary*运算符显式地应用于此指针,或者由于下标而隐式应用于该指针,则结果是指向的(n-1)维数组,如果将其用作除左值之外的其他数据本身将转换为指针.由此得出,数组以行主要顺序存储(最后一个下标变化最快).
对于您的示例,您可以尝试一下并查看 - http://codepad.org/10ylsgPj