简体   繁体   English

二维数组混乱

[英]2d array confusion

为什么二维数组的内存由两个参数而不是仅由一个参数访问(忽略指针)。为什么内存图是基于行和列而不是直的(水平的),还说为什么2d array是一个数组数组,但我不明白。

It's about convenience. 是为了方便。 Sure, the memory's actually all sequential, but sometimes one wants to be able to access things with two indices (eg implementing matrices). 当然,内存实际上是全部顺序的,但是有时人们希望能够使用两个索引访问事物(例如,实现矩阵)。

Consider a 3x3 array. 考虑一个3×3的阵列。 It's convenient to think of the memory like this: 想到这样的内存很方便:

----------------------------
| [0][0] | [0][1] | [0][2] |
|--------------------------|
| [1][0] | [1][1] | [1][2] |
|--------------------------|
| [2][0] | [2][1] | [2][2] |
----------------------------

But in memory, it of course really looks like this: 但是在内存中,它当然确实看起来像这样:

----------------------------------------------------------------------------------
| [0][0] | [0][1] | [0][2] | [1][0] | [1][1] | [1][2] | [2][0] | [2][1] | [2][2] |
----------------------------------------------------------------------------------

We just split it up into rows so that we can easily understand it as two-dimensional. 我们将其分成几行,以便我们可以轻松地将其理解为二维。 We access it with two parameters because we want to, because that's convenient for our code. 我们想要使用两个参数来访问它,因为这对于我们的代码很方便。 The language provides this implementation, which makes it possible to access via two indices, even though under the covers it's linear and could be accessed with one index. 该语言提供了这种实现,即使通过线性方式可以通过一个索引访问,也可以通过两个索引进行访问。

This picture should also help you understand why it can be considered an array of arrays. 此图片还应帮助您理解为什么可以将其视为数组数组。 Here's a slightly modified picture, for emphasis: 这是一张经过稍微修改的图片,以供强调:

|||--------------------------|||--------------------------|||--------------------------|||
||| [0][0] | [0][1] | [0][2] ||| [1][0] | [1][1] | [1][2] ||| [2][0] | [2][1] | [2][2] |||
|||--------------------------|||--------------------------|||--------------------------|||

As you can see, there are really three one-dimensional arrays there. 如您所见,实际上有三个一维数组。 So, when you write array[1] , you are referring to the second one-dimensional component of the full two-dimensional array, ie the second group of three in memory. 因此,当您编写array[1] ,您指的是完整二维数组的第二个一维分量,即内存中的第二个3组。 Adding a second index, array[1][2] takes the third element of that one-dimensional array, getting you down to a single element of the two-dimensional array as desired. 添加第二个索引, array[1][2]将采用该一维数组的第三个元素,根据需要将您带到二维数组的单个元素。

its all about differences between: 关于以下各项的差异:

 1  2  3  4  5  6  7  8  9  
[A][A][A][A][A][X][A][A][A]

and

      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]

find X in above data: 在上述数据中找到X:

in the first one, in order to access to a address you just need ONE index (6 is X location) 在第一个中,为了访问地址,您只需要一个索引(6是X位置)

but in the second one you have TWO index to identify a address (4 : 5 is X location). 但是在第二个中,您有两个索引来标识一个地址(4:5是X位置)。

you can consider second table as a array of first array. 您可以将第二张表视为第一个数组的数组。

Note that Memory Allocation for these arrays are different form what you seeing in my sample. 请注意,这些阵列的内存分配与您在示例中看到的形式有所不同。 My Sample is just for better understanding 我的样本只是为了更好地理解

It is the same reason why you don't write 2 dimensional matrix as a series of integers in your math notebook. 这也是为什么您不在数学笔记本中将二维矩阵写为一系列整数的原因。 It just means that they represent two different features. 这仅表示它们代表两个不同的功能。 For eg the pixels on screen can be represented as a single array using A[i] { i => 0 to N^2 } , but when somebody asks you for the 4th pixel on 10th row, you don't want to do the multiplication yourself everytime right? 例如,可以使用A[i] { i => 0 to N^2 }将屏幕上的像素表示为单个数组,但是当有人问您第10行的第4个像素时,您不想每次都自己繁殖吧? Instead you just return A[10][4] . 相反,您只返回A[10][4]

The answers above are all right. 上面的答案都可以。 But they are telling only half side of the story. 但是他们只讲故事的一半。 Now I am going to tell you the other half where you must and must have two variables to index to the two dimensional array. 现在,我将告诉您另一半,您必须并且必须在其中有两个变量才能索引二维数组。 This is when you are declaring the two dimensional array on the heap instead of stack. 这是在堆上而不是堆栈上声明二维数组时。 A common interview question in C is "How will you dynamically create two dimensional array?". C语言中一个常见的面试问题是“如何动态创建二维数组?”。

The code snippet is as follows :- 代码段如下:

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));

}

In this case if you want to go to third row second column element you can't do like int elem = p[2*n + 1]. 在这种情况下,如果要转到第三行第二列元素,则不能像int elem = p[2*n + 1]. Simple reason being the types are not same p[2*n+1] is of the type int *. 原因很简单,因为类型不同p [2 * n + 1]的类型为int *。 To get the desired element you must do p[2][1]. 要获得所需的元素,必须执行p [2] [1]。

And also please don't ignore the comments to the question. 另外,请不要忽略对该问题的评论。 The natural notion of 2D array is that any elements inside will need two redirection to reach till it. 2D数组的自然概念是内部的任何元素都需要两次重定向才能到达。 Accessing it in one step doesn't make any difference. 一步访问它没有任何区别。 It may not even fasten the things. 它甚至可能无法固定东西。

To know what I am talking about consider an array declared as int p[20][20]; 要知道我在说什么,考虑一个声明为int p[20][20];的数组int p[20][20]; Now if you think that if you accessing p[2][1] is slower than accessing p[2*20 +1], you are wrong again. 现在,如果您认为如果访问p [2] [1]的速度比访问p [2 * 20 +1]的速度慢,那么您又错了。 Why? 为什么? Because internally compiler is doing the same thing. 因为在内部编译器正在执行相同的操作。 At max few microseconds of the compile time will be saved. 最多可节省几微秒的编译时间。 And do you know who cares about saving few microseconds at compile time? 而且您知道谁在乎在编译时节省几微秒的时间吗?

Nobody. 没有人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM