简体   繁体   中英

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. 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. 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.

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:

in the first one, in order to access to a address you just need ONE index (6 is X location)

but in the second one you have TWO index to identify a address (4 : 5 is X location).

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? Instead you just return 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?".

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]. Simple reason being the types are not same p[2*n+1] is of the type int *. To get the desired element you must do 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. 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]; Now if you think that if you accessing p[2][1] is slower than accessing p[2*20 +1], you are wrong again. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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