[英]2d array confusion
为什么二维数组的内存由两个参数而不是仅由一个参数访问(忽略指针)。为什么内存图是基于行和列而不是直的(水平的),还说为什么2d array是一个数组数组,但我不明白。
是为了方便。 当然,内存实际上是全部顺序的,但是有时人们希望能够使用两个索引访问事物(例如,实现矩阵)。
考虑一个3×3的阵列。 想到这样的内存很方便:
----------------------------
| [0][0] | [0][1] | [0][2] |
|--------------------------|
| [1][0] | [1][1] | [1][2] |
|--------------------------|
| [2][0] | [2][1] | [2][2] |
----------------------------
但是在内存中,它当然确实看起来像这样:
----------------------------------------------------------------------------------
| [0][0] | [0][1] | [0][2] | [1][0] | [1][1] | [1][2] | [2][0] | [2][1] | [2][2] |
----------------------------------------------------------------------------------
我们将其分成几行,以便我们可以轻松地将其理解为二维。 我们想要使用两个参数来访问它,因为这对于我们的代码很方便。 该语言提供了这种实现,即使通过线性方式可以通过一个索引访问,也可以通过两个索引进行访问。
此图片还应帮助您理解为什么可以将其视为数组数组。 这是一张经过稍微修改的图片,以供强调:
|||--------------------------|||--------------------------|||--------------------------|||
||| [0][0] | [0][1] | [0][2] ||| [1][0] | [1][1] | [1][2] ||| [2][0] | [2][1] | [2][2] |||
|||--------------------------|||--------------------------|||--------------------------|||
如您所见,实际上有三个一维数组。 因此,当您编写array[1]
,您指的是完整二维数组的第二个一维分量,即内存中的第二个3组。 添加第二个索引, array[1][2]
将采用该一维数组的第三个元素,根据需要将您带到二维数组的单个元素。
关于以下各项的差异:
1 2 3 4 5 6 7 8 9
[A][A][A][A][A][X][A][A][A]
和
1 2 3 4 5 6 7 8
1 [A][A][A][A][A][A][A][A]
2 [A][A][A][A][A][A][A][A]
3 [A][A][A][A][A][A][A][A]
4 [A][A][A][A][X][A][A][A]
5 [A][A][A][A][A][A][A][A]
6 [A][A][A][A][A][A][A][A]
在上述数据中找到X:
在第一个中,为了访问地址,您只需要一个索引(6是X位置)
但是在第二个中,您有两个索引来标识一个地址(4:5是X位置)。
您可以将第二张表视为第一个数组的数组。
请注意,这些阵列的内存分配与您在示例中看到的形式有所不同。 我的样本只是为了更好地理解
这也是为什么您不在数学笔记本中将二维矩阵写为一系列整数的原因。 这仅表示它们代表两个不同的功能。 例如,可以使用A[i] { i => 0 to N^2 }
将屏幕上的像素表示为单个数组,但是当有人问您第10行的第4个像素时,您不想每次都自己繁殖吧? 相反,您只返回A[10][4]
。
上面的答案都可以。 但是他们只讲故事的一半。 现在,我将告诉您另一半,您必须并且必须在其中有两个变量才能索引二维数组。 这是在堆上而不是堆栈上声明二维数组时。 C语言中一个常见的面试问题是“如何动态创建二维数组?”。
代码段如下:
int **p = (int **)malloc(n * sizeof(int*));
for(int i =0;i < n;i++){ p[i] = (int *)malloc(n * sizeof(int));
for(int i =0;i < n;i++){ p[i] = (int *)malloc(n * sizeof(int));
}
在这种情况下,如果要转到第三行第二列元素,则不能像int elem = p[2*n + 1].
原因很简单,因为类型不同p [2 * n + 1]的类型为int *。 要获得所需的元素,必须执行p [2] [1]。
另外,请不要忽略对该问题的评论。 2D数组的自然概念是内部的任何元素都需要两次重定向才能到达。 一步访问它没有任何区别。 它甚至可能无法固定东西。
要知道我在说什么,考虑一个声明为int p[20][20];
的数组int p[20][20];
现在,如果您认为如果访问p [2] [1]的速度比访问p [2 * 20 +1]的速度慢,那么您又错了。 为什么? 因为在内部编译器正在执行相同的操作。 最多可节省几微秒的编译时间。 而且您知道谁在乎在编译时节省几微秒的时间吗?
没有人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.