2D数组与数组数组

Mat*_*haq 11 c c++ multidimensional-array

2D数组和数组数组之间有什么区别?

我读过像@ Dave这样的评论,似乎可以区分这两者.

如果他使用2d数组或指针到数组类型而不是数组数组,则会中断. - 戴夫

我一直认为这两个都提到:

int arr_arr[][];
Run Code Online (Sandbox Code Playgroud)

编辑: @FutureReader,您可能希望看到如何在C++中使用数组?

Dav*_*ave 25

这里有四个不同的概念.

  • 二维数组: 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).相同.

其中每一个都可以使用arr[y][x],导致混乱.

  • 严格来说,只有第一个是二维数组。其他的是可以*模拟*二维数组的数据结构。但是对于所有四种形式,一旦分配了所有内容(这很棘手),就可以使用相同的`arr [x] [y]`语法来访问单个元素。不同之处在于每个[[]`运算符的前缀是指针表达式还是*衰减为指针的数组表达式。有4种组合。(对于3维数组状结构,有8种组合;对于N维,则有2 ** N。) (2认同)

Jac*_*kin 10

根据定义,二维数组数组的数组.

Dave所说的是,在这种情况下,2D数组的定义之间存在不同的语义,如下所示:

int x[][];
Run Code Online (Sandbox Code Playgroud)

这个:

int *x[];
Run Code Online (Sandbox Code Playgroud)

或这个:

int **x;
Run Code Online (Sandbox Code Playgroud)

  • 有时您可能会看到一个2D数组被定义为`int(*x)[10];`,这是一个很好的技巧,可以将一个平面数组变成一个可以用`[x] [y]`索引的二维数组,而不是`[x*width + y]`. (4认同)
  • @muntoo:好的。我认为“不同”可以更清楚地表达这一点。 (2认同)

fos*_*ock 10

这里的答案有点微妙.

数组数组定义如下:

int array2[][];
Run Code Online (Sandbox Code Playgroud)

指向数组的指针类型定义为:

int (*array2)[];
Run Code Online (Sandbox Code Playgroud)

指针数组类型定义为:

int* array2[];
Run Code Online (Sandbox Code Playgroud)

编译器对这两者的处理方式略有不同,实际上还有一个选项:

int** array2;
Run Code Online (Sandbox Code Playgroud)

很多人都被告知这三个是相同的,但如果你对编译器了解得更多,你肯定会知道差异很小,但它确实存在.如果你将一个程序替换为另一个程序,很多程序都会运行,但是在编译器和ASM级别,事情并不相同.关于C编译器的教科书应该提供更深入的答案.

此外,如果有人对2D阵列的实现感兴趣,则根据情况,有多种方法的效率会有所不同.您可以将2D数组映射到1D数组,从而确保在处理线性化数据时的空间局部性.如果希望编程简单,并且需要单独操作行/列,则可以使用数组数组.某些被阻止的类型和其他花哨的设计是缓存智能的,但如果您是用户,则很少需要知道实现.

希望我帮忙!

  • 差异不是"非常小".这是数组和指针之间的区别,这是一个非常重要的区别(也是太多C程序员错过的区别). (3认同)