3D 数组如何在 C 中存储?
据我所知,C 中的数组是按行优先顺序分配的。因此,对于 2 x 3 数组:
0 1
2 3
4 5
存储在内存中为
0 1 2 3 4 5
但是,如果我有一个 2 x 3 x 2 数组怎么办:
0 1
2 3
4 5
这些如何
6 7
8 9
10 11
存储在内存中?只是连续的,例如:
0 1 2 3 4 5 6 7 8 9 10 11
或者是其他方式吗?或者它取决于什么?
I understand that arrays in C are allocated in row-major order. Therefore, for a 2 x 3 array:
0 1
2 3
4 5
Is stored in memory as
0 1 2 3 4 5
However, what if I have a 2 x 3 x 2 array:
0 1
2 3
4 5
and
6 7
8 9
10 11
How are these stored in memory? Is just consecutive like:
0 1 2 3 4 5 6 7 8 9 10 11
Or is it some other way? Or does it depend on something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在低层次上,不存在多维数组这样的东西。只有一块平坦的内存块,足够大以容纳给定数量的元素。在 C 语言中,多维数组在概念上是其元素也是数组的数组。因此,如果您这样做:
从概念上讲,您最终会得到:
这会导致元素在内存中连续排列,因为
array[0]
和array[1]
实际上并未保存任何数据,它们只是对两个内部数组的引用。请注意,这意味着只有[0, 1, 2]
条目实际占用内存空间。如果将此模式扩展到下一个维度,您可以看到:...将为您提供如下结构:
继续在内存中连续排列元素(如上所述,只有
[0, 1] 条目实际上占用内存中的空间,其他所有内容只是对这些条目之一的引用的一部分)。正如您所看到的,无论您有多少个维度,这种模式都会持续下去。
只是为了好玩:
给你:
At a low level, there is no such thing as a multi-dimensional array. There is just a flat block of memory, large enough to hold a given number of elements. In C, a multi-dimensional array is conceptually an array whose elements are also arrays. So if you do:
Conceptually you end up with:
This results in the elements being arranged contiguously in memory, because
array[0]
andarray[1]
are not actually holding any data, they are just references to the two inner arrays. Note that this means that only the[0, 1, 2]
entries actually occupy space in memory. If you extend this pattern out to the next dimension, you can see that:...will give you a structure like:
Which continues arranging the elements consecutively in memory (as above, only the
[0, 1]
entries actually occupy space in memory, everything else is just part of a reference to one of these entries). As you can see, this pattern will continue no matter how many dimensions you have.And just for fun:
Gives you:
所有“维度”都连续存储在内存中。
假设
您可以说
arr[1]
和arr[2]
(类型为int[100][20]
)是连续的或者
arr[1][42]
和arr[1][43]
(类型为int[20]
)是连续的或者 arr[1][42][7] 和 arr[1][42][8] (类型为
int
)连续的All "dimensions" are stored consecutively in memory.
Consider
you can say that
arr[1]
andarr[2]
(of typeint[100][20]
) are contiguousor that
arr[1][42]
andarr[1][43]
(of typeint[20]
) are contiguousor that
arr[1][42][7]
andarr[1][42][8]
(of typeint
) are contiguous是的,你是对的 - 它们是连续存储的。考虑这个例子:
输出:
0 1 2 3 3 4 5 6 7 8 9 10
Yep, you're right - they are stored consecutively. Consider this example:
Output:
0 1 2 3 3 4 5 6 7 8 9 10
是的,它们只是按连续顺序存储。您可以这样测试:
这意味着对维度为 (N,M,L) 的多索引数组的访问将转换为一维访问,如下所示:
Yes, they're are just stored in consecutive order. You can test that like this:
That means that accesses to a multiindexed array with dimensions (N,M,L) are transformed to onedimensional accesses like this:
我想你已经回答了你自己的问题。多维数组按行优先顺序存储。
参见ANSI C规范第3.3.2.1节(还有一个具体的例子):
对于您的示例,您可以尝试一下并查看 - http://codepad.org/10ylsgPj
I think you have answered your own question. Multi-dimensional arrays are stored in row-major order.
See ANSI C specification section 3.3.2.1 (there is also a specific example):
For your example, you can just try it out and see - http://codepad.org/10ylsgPj
假设您有一个数组
char arr[3][4][5]
。它是一个由 3 个数组组成的数组,每个数组由 4 个 5 个字符的数组组成。为简单起见,假设 arr[x][y][z] 中的值为
xyz
,而 arr[1][2][3] 中的值为xyz
我们存储123
。所以内存中的布局是:
arr[0]
、arr[1]
和arr[2]
依次到来,但是每一个中的元素的类型为 char[4][5](这些是表中的三行)。arr[x][0] - arr[x][3]
也是依次出现,其中的每个元素都是char[5]
类型(那些是表中每一行的四个部分,000 - 004 是 arr[0][0] 的一个元素 )arr[x][y][0] - arr[x ][y][4] 是依次出现的 5 个字节。
Let's say you have an array
char arr[3][4][5]
. It is an array of 3 arrays of 4 arrays of 5 chars.For simplicity, let's say that the value in
arr[x][y][z]
isxyz
and inarr[1][2][3]
we store123
.So the layout in memory is:
arr[0]
,arr[1]
andarr[2]
are coming one after another, but each element in the is of typechar[4][5]
(those are the three rows in the table).arr[x][0] - arr[x][3]
are also coming one after another, and each element in them is of typechar[5]
(those are the four parts of each line in the table, 000 - 004 is one element ofarr[0][0]
)arr[x][y][0] - arr[x][y][4]
are 5 bytes that are coming one after another.回答OP对主要问题的评论(它会有点长,所以我决定给出答案,而不是评论):
在数学中,MxN 矩阵有 M 行和 N 列。矩阵元素的常用表示法是a(i,j), 1<=i<=M, 1<=j<=N。所以你问题中的第一个矩阵是 3x2 矩阵。
事实上,它与通常用于 GUI 元素等的符号不同。 800x600 位图水平方向(沿 X 轴)有 800 个像素,垂直方向(沿 Y 轴)有 600 个像素。如果有人想将其描述为矩阵,那么用数学表示法来说,它将是一个 600x800 矩阵(600 行,800 列)。
现在,C 中的多维数组在内存中的存储方式是
a[i][j+1]
紧邻a[i][j]
,而 < code>a[i+1][j] 距离 N 个元素。通常说“最后一个下标变化最快”,或者通常称为“按行存储”:二维矩阵中的一行(即具有相同第一个索引的元素)连续放置在内存中,而一列(相同的第二个索引) )由彼此远离的元素组成。出于性能考虑,了解这一点很重要:对邻居元素的访问通常要快得多(由于硬件缓存等),因此,例如,应组织嵌套循环,以便最里面的循环遍历最后一个索引。回到问题:如果你心目中的二维数组(抽象)是笛卡尔坐标中的格子,那么是的,你可以将其视为 C 中的 array[NY][NX]但是,如果您需要将真实的 2D 或 3D 数据描述为数组,则索引的选择可能取决于其他因素:数据格式、方便的表示法、性能等。例如,如果位图的内存中表示为 < 。 code>array[NX][NY] 以您需要使用的格式,您将这样声明它,也许您甚至不需要知道位图变得有点“转置”:)
To answer OP's comment to the main question (it will be somewhat long, so I decided to go with an answer, not a comment):
In math, a MxN matrix has M rows and N columns. A usual notation for a matrix element is
a(i,j), 1<=i<=M, 1<=j<=N
. So the first matrix in your question is a 3x2 matrix.Indeed it is different from the notation typically used for e.g. GUI elements. A 800x600 bitmap has 800 pixels horizontally (along X axis) and 600 pixels vertically (along Y axis). If some would want to describe it as a matrix, in math notation it would be a 600x800 matrix (600 rows, 800 columns).
Now, multidimensional arrays in C are stored in memory in such a way that
a[i][j+1]
is next toa[i][j]
whilea[i+1][j]
is N elements away. It is usually said that "the last subscript varies fastest", or often as "stored by rows": a row (i.e. elements with same first index) in a 2-dimensional matrix has placed contiguously in memory while a column (same second index) consist of elements lying far away from each other. It is important to know for performance considerations: access to neighbor elements is usually much faster (due to HW caches etc.), so for example nested loops should be organized such that the innermost one iterates over the last index.Back to the question: if your mental picture (abstraction) of a 2D array is that of a lattice in Carthesian coordinates, then yes, you may think of it as
array[NY][NX]
in C. However if you need to describe real 2D or 3D data as an array, the choice of indexes probably depends on other things: data formats, convenient notation, performance, etc. For example, if the in-memory representation for a bitmap isarray[NX][NY]
in a format you need to work with, you will declare it that way, and maybe you don't even need to know that the bitmap becomes sort of "transposed" :)3d 数组是一个扩展的 2d 数组。
例如我们有一个数组 -
int arr(3)(5)(6);
这是一个由两个 2d 数组组成的数组,其中 array 将有一个 4 行 3 列的 2d 数组。
3d array is an extended 2d array.
For example we have an array -
int arr(3)(5)(6);
This is an array which consists of two 2d arrays where array would have a 2d array having 4 rows and 3 columns.