3

I have some problem understanding the pointers syntax usage in context with two dimensional arrays, though I am comfortable with 1-D array notation and pointers, below is one of the syntax and I am not able to understand how the following expression is evaluated.

To access the element stored at third row second column of array a we will use the subscripted notation as a[2][1] other way to access the same element is

*(a[2]+1)

and if we want to use it as pointers we will do like this

*(*(a+2)+1)

Though I am able to understand the replacement of *(a[2]+1) as *(*(a+2)+1) but I don't know how this is getting evaluated. Please explain with example if possible. Assume array is stored in row wise order and contain the following elements

int a[5][2]={
               21,22,
               31,32
               41,42,
               51,52,
               61,62
             };

and base address of array is 100(just assume) so the address of a[2] is 108 (size of int =2(another assumption)) So the expression *(*(a+2)+1). How does it gets evaluated does it start from the inside bracket and if it does then after the first bracket we have the value to which 1 is being added rather than the address... :/

2
  • 3
    For any array x, the expression x[i] is identical to *(x + i). Take it from there, considering that x[i] may itself be an array. Commented Jan 13, 2015 at 10:08
  • Din't you get any duplicates of this question? It might already have an elaborated answer, I believe. Commented Jan 13, 2015 at 10:09

2 Answers 2

4

To start of with

a[i] = *(a+i);

So

a[i][j] = *(a[i] +j)

and

a[i][j] = *(*(a+i) + j) 

How a[i] = *(a+i):

If a is a array then the starting address of the array is given by &a[0] or just a

So when you specify

a[i] this will decay to a pointer operation *(a+i) which is, start at the location a and dereference the pointer to get the value stored in the location.

If the memory location is a then the value stored in it is given by *a.

Similarly the address of the next element in the array is given by

&a[1] = (a+1); /* Array decays to a pointer */

Now the location where the element is stored in given by &a[1] or (a+1) so the value stored in that location is given by *(&a[1]) or *(a+1)

For Eg:

int a[3];

They are stored in the memory as shown below:

  a    a+1   a+2
------------------
| 100 | 102 | 104| 
------------------
 &a[0] &a[1] &a[2]

Now a is pointing to the first element of the array. If you know the pointer operations a+1 will give you the next location and so on.

In 2D arrays the below is what the access is like :

int arr[m][n];



  arr:
        will be pointer to first sub array, not the first element of first sub 
        array, according to relationship of array & pointer, it also represent 
        the array itself,

    arr+1:
        will be pointer to second sub array, not the second element of first sub 
        array,

    *(arr+1):
        will be pointer to first element of second sub array,
        according to relationship of array & pointer, it also represent second
        sub array, same as arr[1],

    *(arr+1)+2:
        will be pointer to third element of second sub array,

    *(*(arr+1)+2):
        will get value of third element of second sub array,
        same as arr[1][2],
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks but as mentioned in the question, Though I am able to understand the replacement of *(a[2]+1) as *(*(a+2)+1) but I don't know how this is getting evaluated. Please explain with example if possible
@Karan Check the edits and let me know whether it helped or not
@Karan Hmmmm. I have explained what I could take a look
The sub-expression *(a+2) in *(*(a+2)+1) will give a value rather than an address rt. So how come a *(value+1) will give the another value..?
@Karan In 2D space you a double pointer int **a; then *a will be a pointer you get it?
|
4

A 2D array is actually a consecutive piece of memory. Let me take a example : int a[3][4] is representend in memory by a unique sequence of 12 integer :

a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24
|                   |                   |
first row           second row          third row

(of course it can be extended to any muti-dimensional array)

a is an array of int[4] : it decays to a pointer to int[4] (in fact, it decays to &(a[0]))

a[1] is second row. It decays to a int * pointing to beginning of first row.

Even if arrays are not pointer, the fact that they decay to pointers allows to use them in pointer arithmetic : a + 1 is a pointer to second element of array a.

All that explains why a[1] == *(a + 1)

The same reasoning can be applied to a[i] == *(a+i), and from there to all the expressions in your question.

Let's look specifically to *(*(a+2)+1). As said above, a + 2 is a pointer to the third element of an array of int 4. So *(a + 2) is third row, is an array of int[4] and decays to a int * : &(a[2][0]).

As *(a + 2) decays to an int *, we can still use it as a base for pointer arithmetic and *(a + 2) + 1 is a pointer to the second element of third row : *(a + 2) + 1 == &(a[2][1]). Just dereference all that and we get

*(*(a + 2) + 1) == a[2][1]

1 Comment

Check my comment in the above answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.