C++ 二维数组与数组数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7949589/
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
2D array vs array of arrays
提问by Mateen Ulhaq
What is the difference between a 2D array and an array of arrays?
二维数组和数组数组有什么区别?
I have read comments, such as @Dave's, that seem to differentiate between the two.
我读过评论,例如@Dave's,似乎区分了两者。
This breaks if he's using 2d arrays, or pointer-to-array types, rather than an array of arrays. – Dave
如果他使用二维数组或指向数组的类型,而不是数组的数组,这会中断。– 戴夫
I always thought that both referred to:
我一直认为两者都指的是:
int arr_arr[][];
EDIT:@FutureReader, you may wish to see How do I use arrays in C++?
编辑:@FutureReader,您可能希望查看如何在 C++ 中使用数组?
采纳答案by Jacob Relkin
A 2 dimensional array isby definition an array of arrays.
根据定义,二维数组是数组的数组。
What Dave was saying is that in that context, there are different semantics between the definition of a 2D array like this:
Dave 所说的是,在这种情况下,像这样的 2D 数组的定义之间存在不同的语义:
int x[][];
this:
这个:
int *x[];
or this:
或这个:
int **x;
回答by Dave
There are four different concepts here.
这里有四个不同的概念。
- The two-dimensional array:
int arr[][]
. It cannot be resized in any direction, and is contiguous. Indexing it is the same as((int*)arr)[y*w + x]
. Must be allocated statically. - The pointer-to array:
int (*arr)[]
. It can be resized only to add more rows, and is contiguous. Indexing it is the same as((int*)arr)[y*w + x]
. Must be allocated dynamically, but can be freedfree(x)
; - The pointer-to-pointer:
int **arr
. It can be resized in any direction, and isn't necessarily square. Usually allocated dynamically, not necessarily contiguous, and freeing is dependent on its construction. Indexing is the same as*(*(arr+y)+x)
. - The array-of-pointers:
int *arr[]
. It can be resized only to add more columns, and isn't necessarily square. Resizing and freeing also depends on construction. Indexing is the same as*(*(arr+y)+x)
.
- 二维数组:
int arr[][]
. 它不能向任何方向调整大小,并且是连续的。索引它与((int*)arr)[y*w + x]
. 必须静态分配。 - 指向数组的指针:
int (*arr)[]
. 它只能调整大小以添加更多行,并且是连续的。索引它与((int*)arr)[y*w + x]
. 必须动态分配,但可以释放free(x)
; - 指针到指针:
int **arr
. 它可以向任何方向调整大小,不一定是方形的。通常动态分配,不一定是连续的,释放取决于其构造。索引与*(*(arr+y)+x)
. - 指针数组:
int *arr[]
. 它只能调整大小以添加更多列,并且不一定是正方形。调整大小和释放也取决于构造。索引与*(*(arr+y)+x)
.
Every one of these can be used arr[y][x]
, leading to the confusion.
这些中的每一个都可以使用arr[y][x]
,导致混乱。
回答by foslock
The answer here is a little more subtle.
这里的答案更微妙一些。
An array of arrays is defined as such:
数组的数组定义如下:
int array2[][];
The pointer-to-array types are defined as:
指向数组的指针类型定义为:
int (*array2)[];
The array-of-pointer types are defined as:
指针数组类型定义为:
int* array2[];
The compiler treats both of these a little differently, and indeed there is one more option:
编译器对这两者的处理方式略有不同,实际上还有一种选择:
int** array2;
A lot of people are taught that these three are identical, but if you know more about compilers you will surely know that difference is small, but it is there. A lot of programs will run if you substitute one for another, but at the compiler and ASM level things are NOT the same. A textbook on C compilers should provide a much more in depth answer.
很多人被教导说这三个是相同的,但是如果您对编译器了解更多,您肯定会知道差异很小,但确实存在。如果你用一个替换另一个,很多程序都会运行,但是在编译器和 ASM 级别,事情是不一样的。C 编译器的教科书应该提供更深入的答案。
Also, if one is interested in the implementation of a 2D array there are multiple methods that vary in efficiency, depending on the situation. You can map a 2D array to a 1D array, which ensures spacial locality when dealing with linearized data. You can use the array of arrays if you want the ease of programming, and if you need to manipulate the rows/columns separately. There are certain blocked types and other fancy designs that are cache-smart, but rarely do you need to know the implementation if you the user.
此外,如果对 2D 数组的实现感兴趣,则有多种效率不同的方法,具体取决于具体情况。您可以将二维数组映射到一维数组,从而在处理线性化数据时确保空间局部性。如果您想要易于编程,并且需要单独操作行/列,则可以使用数组数组。有某些阻塞类型和其他花哨的设计是缓存智能的,但如果你是用户,你很少需要知道实现。
Hope I helped!
希望我有所帮助!
回答by Chris Lutz
The following is a 2D array that can be called an array of arrays:
下面是一个二维数组,可以称为数组数组:
int AoA[10][10];
The following is a pointer to a pointer that has been set up to function as a 2D array:
以下是一个指向已设置为用作 2D 数组的指针的指针:
int **P2P = malloc(10 * sizeof *P2P);
if(!P2P) exit(1);
for(size_t i = 0; i < 10; i++)
{
P2P[i] = malloc(10 * sizeof **P2P);
if(!P2P[i])
{
for(; i > 0; i--)
free(P2P[i - 1]);
free(P2P);
}
}
Both can be accessed via AoA[x][y]
or P2P[x][y]
, but the two are incompatible. In particular, P2P = AoA
is something that newbies sometimes expect to work, but will not - P2P
expects to point to pointers, but when AoA
decays into a pointer, it is a pointer to an array, specifically int (*)[10]
, which is not the int **
that P2P
is supposed to be.
两者都可以通过AoA[x][y]
或访问P2P[x][y]
,但两者不兼容。尤其P2P = AoA
是一些新手有时期望的工作,但不会-P2P
预计将指向指针,但是当AoA
衰变为指针,它是一个指针到一个数组,特别是int (*)[10]
,这是不是int **
说P2P
应该是。
回答by Pubby
2d array can include this:
二维数组可以包括:
int x[width * height]; // access: x[x + y * width];
From Wikipedia:
来自维基百科:
For a two-dimensional array, the element with indices i,j would have address B + c · i + d · j, where the coefficients c and d are the row and column address increments, respectively.
对于二维数组,索引为 i,j 的元素的地址为 B + c · i + d · j,其中系数 c 和 d 分别是行和列地址增量。