1

Note that this has probably been answered before, but now in a way that I could understand it.

I'm trying to understand how pointers and arrays work together. I thought I understood both how and why 1D and 2D arrays could be accessed with pointers until I tried to wrap my head around 3D arrays (just to be clear, I understand 3D arrays, just not how to access them with pointers).

So let's say I have an array x[5] and I want to access the element x[1] using pointers. In that case, I can use *(&x[0]+1), because x is the same as &x[0] and *(x + 1) can be used to access a[1].

Now, for a 2D array, let's say it is declared as x[5][3].

To access x[1][2], I can use *(&x[0][0]+3*1+2). I can kind of understand this. We start at memory location x[0][0], then add 3 * 1 to get from x[0][0] to x[1][0], and then add 2 to get from x[1][0] to x[1][2].

The above makes sense to me until I get to a three dimensional array. Let's assume that x is declared as x[3][4][5], how would I get to, let's say element x[2][1][3] using the same logic(if possible)? Also, how can I apply this logic to higher dimensional arrays as well?

Any advice on this is greatly appreciated!

Lobs001
  • 365
  • 4
  • 14
  • 1
    "x is the same as &x[0]" - **NOOO**. (sorry for shouting, but that has been asked and answered and discussed here way toooo often already!) - Do research! Hint: An array **is not a pointer**. – too honest for this site Apr 21 '17 at 00:04
  • 1
    @Olaf ok, fair enough but 1. I got that information by actually doing research. 2. I don't keep up with all discussions going on here. 3. they return the same value. 4. My question was about accessing arrays using pointers, so while that particular statement may have been technically incorrect, it doesn't change what I want to know :) – Lobs001 Apr 21 '17 at 00:12
  • @Olaf Also, can you point me to a good explanation of what the difference between the two statements is? I'm just curious...and the more you know the better :) – Lobs001 Apr 21 '17 at 00:16
  • 1
    You may glean a lot from [**Array of pointers to an array of fixed size**](http://stackoverflow.com/questions/37348741/array-of-pointers-to-an-array-of-fixed-size) there are a **LARGE** number of very good and very **RELEVANT** answers there. (and loosely in your defense, it can be a challenge to pick out the relevant answers from 10,231 search results, but with diligence, it can be done) If you still have questions after digesting that answer, edit your question here and add specifics. – David C. Rankin Apr 21 '17 at 00:39
  • @DavidC.Rankin Thank you! I will look through it once I get home later today and update my q if there's more to add. – Lobs001 Apr 21 '17 at 00:53
  • If you have, say, `int x[3][4][5];` and `p` is an `int *` pointing to `x[0][0][0]`, then `*(p + 5*4*2 + 5*1 + 3)` will let you access `x[2][1][3]` via `p`. The index at the finest dimension, single elements, is `3`, which gives the `+ 3` at the end. The next larger dimension is arrays of 5 elements, so its index of `1` gives the `+ 5*1`. The largest dimension is for arrays of 4 arrays of 5 elements, so its index of `2` gives the `+ 5*4*2`... all together, you offset by `5*4*2 + 5*1 + 3` elements. – Dmitri Apr 21 '17 at 02:06
  • @Lobs001, while you read the other relevant links, read them in light of `x[i][j][k] == (*(x + i))[j][k] == *(x[i][j] + k) == (*(*(x + i) + j))[k] == *(*(x[i] + j) + k) == *(*(*(x + i) + j) + k)` and in doing so, make sure you understand why the extra *parenthesis* are required around `(*(x + i))[j][k]` and not `*(x[i][j] + k)`? And why `x[]` is not a pointer, but what happens to `x` in, e.g. `printf (x: %p\n", (void *)x);` (or anywhere `x` is passed as a *parameter to a function*) – David C. Rankin Apr 21 '17 at 02:24

2 Answers2

0

Supposing you have the following array:

//x[i][j][k]
int x[2][3][5] = { {{0,1,2,3,4},
                    {5,6,7,8,9},
                    {10,11,12,13,14}},

                    {{ 88,1,2,3,4 },
                    { 5,6,7,8,9},
                    { 10,11,12,77,14}} 
                };

Elements of 3D array are arranged in series in the memory like this:

{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{ 88,1,2,3,4 },{ 5,6,7,8,9},{ 10,11,12,77,14}

Obviously, If you hava the address of the first element you can access the others by adding an offset. The address of the first element is **x, and the address of the next one is **x+1 and so forth. To access the elements of the x array look at the following example:

    int D3_width = sizeof(x)/sizeof(x[0]); //2
    int D2_width = sizeof(x[0]) / sizeof(x[0][0]); //3
    int D1_width = sizeof(x[0][0]) / sizeof(int); //5

    int i = 0, j = 2, k = 3;
    cout << *(**x + i*D2_width*D1_width + j*D1_width + k);

    output:13

You can use the same approach for other multi-dimensional arrays.

The formula is tested and works perfectly.

Macit
  • 276
  • 3
  • 10
  • @AjayBrahmakshatriya I think in `**x`, `x` decays to `int (*)[3][5]`, which is dereferenced to `int [3][5]`, which decays to `int (*)[5]`, which is dereferenced to `int [5]`, which decays to `int *`... so `**x` gives an `int *`, in a rather confusing way. I'd avoid it personally, but it seems to work. – Dmitri Apr 21 '17 at 04:33
  • @Dmitri Ah, I misread some parts. Will delete my comment. Thanks. – Ajay Brahmakshatriya Apr 21 '17 at 04:47
-1

For a two-dimensional array you can skip through indexes of rows with pointer arithmetic as you were doing:

First index of first row + (length of row * desired Row)

If you are making your way up the dimensions, this expression will start to get rather large.

For 3D:

First index of first plane + (size of plane * desired plane)

Note that the plane is a 2-dimensional structure.

Now moving into 4D:

First index of first cube + (size of cube * desired cube )

Hope you get the idea.

Patrick
  • 90
  • 2
  • 8