2Darrays与arraysarrays

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

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

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

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

int arr_arr[][]; 

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

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

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

 int x[][]; 

这个:

 int *x[]; 

或这个:

 int **x; 

这里有四个不同的概念。

  • 二维数组: int arr[][] 。 它不能在任何方向resize,并且是连续的。 索引它与((int*)arr)[y*w + x] 。 必须静态分配。
  • 指针数组: int (*arr)[] 。 它只能resize以添加更多行,并且是连续的。 索引它与((int*)arr)[y*w + x] 。 必须动态分配,但可以自由释放free(x) ;
  • 指向指针的指针: int **arr 。 它可以在任何方向上resize,并且不一定是方形的。 通常动态分配,不一定是连续的,并且释放取决于其构造。 索引与*(*(arr+y)+x)
  • 指针数组: int *arr[] 。 它只能resize以添加更多列,并且不一定是正方形。 resize和释放也取决于结构。 索引与*(*(arr+y)+x)

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

这里的答案有点微妙。

数组数组定义如下:

 int array2[][]; 

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

 int (*array2)[]; 

定义了一个指针数组类型:

 int* array2[]; 

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

 int** array2; 

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

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

希望我帮忙!

以下是可以称为数组数组的2D数组:

 int AoA[10][10]; 

以下是指向已设置为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); } } 

两者都可以通过AoA[x][y]P2P[x][y] ,但两者是不兼容的。 特别是, P2P = AoA是新手有时期望工作的东西,但不会 – P2P期望指向指针,但当AoA衰变成指针时,它是指向数组的指针,特别是int (*)[10] ,这不是P2P应该是的int **

2d数组可以包括:

 int x[width * height]; // access: x[x + y * width]; 

来自维基百科:

对于二维arrays,具有索引i,j的元素将具有地址B + c·i + d·j,其中系数c和d分别是行和列地址增量。