C语言 3D 数组如何存储在 C 中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5920944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How are 3D arrays stored in C?
提问by robintw
I understand that arrays in C are allocated in row-major order. Therefore, for a 2 x 3 array:
我知道 C 中的数组是按行优先顺序分配的。因此,对于 2 x 3 数组:
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:
但是,如果我有一个 2 x 3 x 2 数组怎么办:
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?
或者是其他方式?还是取决于什么?
采纳答案by pmg
All "dimensions" are stored consecutively in memory.
所有“维度”都连续存储在内存中。
Consider
考虑
int arr[4][100][20];
you can say that arr[1]and arr[2](of type int[100][20]) are contiguous
or that arr[1][42]and arr[1][43](of type int[20]) are contiguous
or that arr[1][42][7]and arr[1][42][8](of type int) are contiguous
你可以说arr[1]和arr[2](类型int[100][20])是连续的,
或者arr[1][42]和arr[1][43](类型int[20])是连续的,
或者arr[1][42][7]和arr[1][42][8](类型int)是连续的
回答by aroth
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:
在低层次上,没有多维数组这样的东西。只有一个扁平的内存块,大到足以容纳给定数量的元素。在 C 中,多维数组在概念上是一个数组,其元素也是数组。所以如果你这样做:
int array[2][3];
Conceptually you end up with:
从概念上讲,您最终会得到:
array[0] => [0, 1, 2]
array[1] => [0, 1, 2]
This results in the elements being arranged contiguously in memory, because array[0]and array[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:
这导致元件被连续地布置在存储器中,因为array[0]和array[1]实际上没有保持任何数据,它们对两个内阵列只是引用。请注意,这意味着只有[0, 1, 2]条目实际占用内存空间。如果将此模式扩展到下一个维度,您可以看到:
int array[2][3][2];
...will give you a structure like:
...会给你一个结构,如:
array[0] => [0] => [0, 1]
[1] => [0, 1]
[2] => [0, 1]
array[1] => [0] => [0, 1]
[1] => [0, 1]
[2] => [0, 1]
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.
它继续在内存中连续排列元素(如上所述,只有[0, 1]条目实际占用内存空间,其他所有内容都只是对这些条目之一的引用的一部分)。如您所见,无论您有多少维度,这种模式都会继续。
And just for fun:
只是为了好玩:
int array[2][3][2][5];
Gives you:
给你:
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]
回答by sje397
Yep, you're right - they are stored consecutively. Consider this example:
是的,你是对的 - 它们是连续存储的。考虑这个例子:
#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;
}
Output:
输出:
0 1 2 3 3 4 5 6 7 8 9 10
0 1 2 3 3 4 5 6 7 8 9 10
回答by Thies Heidecke
Yes, they're are just stored in consecutive order. You can test that like this:
是的,它们只是按连续顺序存储。你可以这样测试:
#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;
}
That means that accesses to a multiindexed array with dimensions (N,M,L) are transformed to onedimensional accesses like this:
这意味着对具有维度 (N,M,L) 的多索引数组的访问被转换为这样的一维访问:
array[i][j][k] = array[M*L*i + L*j + k]
回答by CodeButcher
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):
参见ANSI C规范第3.3.2.1节(也有具体例子):
Successive subscript operators designate a member of a multi-dimensional array object. If E is an n -dimensional array ( n =2) with dimensions i x j "x ... x" k , then E (used as other than an lvalue) is converted to a pointer to an ( n -1)-dimensional array with dimensions j "x ... x" k . If the unary * operator is applied to this pointer explicitly, or implicitly as a result of subscripting, the result is the pointed-to ( n -1)-dimensional array, which itself is converted into a pointer if used as other than an lvalue. It follows from this that arrays are stored in row-major order (last subscript varies fastest).
连续的下标运算符指定多维数组对象的成员。如果 E 是维度为 ixj "x ... x" k 的 n 维数组 ( n =2) ,则 E(用作左值以外的其他形式)将转换为指向 ( n -1) 维数组的指针尺寸 j "x ... x" k 。如果将一元 * 运算符显式应用于此指针,或作为下标的结果隐式应用,则结果是指向 (n -1) 维的数组,如果用作非左值,则该数组本身将转换为指针. 因此,数组以行优先顺序存储(最后一个下标变化最快)。
For your example, you can just try it out and see - http://codepad.org/10ylsgPj
对于您的示例,您可以尝试一下并查看 - http://codepad.org/10ylsgPj
回答by MByD
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.
假设您有一个数组char arr[3][4][5]。它是一个由 3 个数组组成的数组,每个数组包含 5 个字符的 4 个数组。
For simplicity, let's say that the value in arr[x][y][z]is xyzand in arr[1][2][3]we store 123.
为简单起见,假设 in 中的值arr[x][y][z]isxyz和 in arr[1][2][3]we store 123。
So the layout in memory is:
所以内存中的布局是:
| 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
--+--------------------------------------------------------------------------------
00| 000 001 002 003 004 010 011 012 013 014 020 021 022 023 024 030 031 032 033 034
20| 100 101 102 103 104 110 111 112 113 114 120 121 122 123 124 130 131 132 133 134
40| 200 201 202 203 204 210 211 212 213 214 220 221 222 223 224 230 231 232 233 234
arr[0], arr[1]and arr[2]are coming one after another, but each element in the is of type char[4][5](those are the three rows in the table).
arr[0],arr[1]并且arr[2]一个接一个地出现,但是 中的每个元素都是类型char[4][5](即表中的三行)。
arr[x][0] - arr[x][3]are also coming one after another, and each element in them is of type char[5](those are the four parts of each line in the table, 000 - 004 is one element of arr[0][0])
arr[x][0] - arr[x][3]也一个接一个出现,其中的每个元素都是类型char[5](这些是表中每行的四个部分,000 - 004 是 的一个元素arr[0][0])
arr[x][y][0] - arr[x][y][4]are 5 bytes that are coming one after another.
arr[x][y][0] - arr[x][y][4]是 5 个字节一个接一个地出现。
回答by Alexey Kukanov
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):
回答 OP 对主要问题的评论(会有点长,所以我决定回答,而不是评论):
Should arrays in C be declared as
array[ny][nx]wherenyandnxare the number of elements in the y and x direction. Furthermore, does that mean that my 3D array should be declared asarray[nz][ny][nx]?
C 中的数组是否应该声明为
array[ny][nx]whereny和nx是 y 和 x 方向上的元素数。此外,这是否意味着我的 3D 数组应该声明为array[nz][ny][nx]?
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.
在数学中,一个 MxN 矩阵有 M 行 N 列。矩阵元素的常用符号是a(i,j), 1<=i<=M, 1<=j<=N。所以你问题中的第一个矩阵是一个 3x2 矩阵。
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).
实际上,它不同于通常用于例如 GUI 元素的符号。800x600 位图水平(沿 X 轴)有 800 个像素,垂直(沿 Y 轴)有 600 个像素。如果有人想将其描述为矩阵,在数学符号中,它将是一个 600x800 矩阵(600 行,800 列)。
Now, multidimensional arrays in C are stored in memory in such a way that a[i][j+1]is next to a[i][j]while a[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.
现在,C 中的多维数组以一种方式存储在内存中,a[i][j+1]即靠近a[i][j]而a[i+1][j]N 个元素。通常说“最后一个下标变化最快”,或者经常说“按行存储”:二维矩阵中的一行(即具有相同第一个索引的元素)连续放置在内存中,而一列(相同的第二个索引) ) 由彼此远离的元素组成。出于性能考虑,重要的是要知道:访问相邻元素通常要快得多(由于硬件缓存等),因此例如应该组织嵌套循环,以便最里面的循环遍历最后一个索引。
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 is array[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" :)
回到问题:如果您对 2D 数组的心理图片(抽象)是 Carthesian 坐标中的格子,那么是的,您可以将其视为array[NY][NX]在 C 中。但是,如果您需要将真实的 2D 或 3D 数据描述为数组,索引的选择可能取决于其他因素:数据格式、方便的表示法、性能等。例如,如果位图的内存表示是array[NX][NY]您需要使用的格式,您将以这种方式声明它,也许你甚至不需要知道位图变成了某种“转置”:)
回答by sukanta mondal
3d array is an extended 2d array.
3d 数组是一个扩展的 2d 数组。
For example we have an array - int arr(3)(5)(6);
例如我们有一个数组 - 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.
这是一个由两个二维数组组成的数组,其中数组将有一个 4 行 3 列的二维数组。

