52

I have a question about a pointer to 2d array. If an array is something like

int a[2][3];

then, is this a pointer to array a?

int (*p)[3] = a;

If this is correct, I am wondering what does [3] mean from int(*p)[3]?

cpx
  • 17,009
  • 20
  • 87
  • 142
user1047092
  • 1,481
  • 4
  • 17
  • 18

6 Answers6

43
int a[2][3];

a is read as an array 2 of array 3 of int which is simply an array of arrays. When you write,

int (*p)[3] = a;

It declares p as a pointer to the first element which is an array. So, p points to the array of 3 ints which is a element of array of arrays.

Consider this example:

        int a[2][3]
+----+----+----+----+----+----+
|    |    |    |    |    |    |
+----+----+----+----+----+----+
\_____________/
       |
       |    
       |
       p    int (*p)[3]

Here, p is your pointer which points to the array of 3 ints which is an element of array of arrays.

cpx
  • 17,009
  • 20
  • 87
  • 142
  • wouldn't "p" become an array of 3 integer pointers, with the first value pointing to the first value of "a"? – Matthew Dec 23 '11 at 17:19
40

Rather than referring to int[2][3] as a '2d array', you should consider it to be an 'array of arrays'. It is an array with two items in it, where each item is itself an array with 3 ints in it.

int (*p)[3] = a;

You can use p to point to either of the two items in a. p points to a three-int array--namely, the first such item. p+1 would point to the second three-int array. To initialize p to point to the second element, use:

int (*p)[3] = &(a[1]);

The following are equivalent ways to point to the first of the two items.

int (*p)[3] = a; // as before
int (*p)[3] = &(a[0]);
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
  • 2
    You could even write `[3]a` for example :) It's a good way of learning what arrays in C really are. – vsz Dec 23 '11 at 16:00
  • 1
    How much memory does this declaration take: `int (*p)[65];`?? Is this one pointer, or 65 pointers? – Danijel May 07 '18 at 10:00
12

Stricly speaking, no, int (*p)[3] = a; is not a pointer to a. It is a pointer to the first element of a. The first element of a is an array of three ints. p is a pointer to an array of three ints.

A pointer to the array a would be declared thus:

int (*q)[2][3] = &a; 

The numeric value of p and q are likely (or maybe even required to be) the same, but they are of different types. This will come into play when you perform arithmetic on p or q. p+1 points to the second element of array a, while q+1 points to the memory just beyond the end of array a.

Remember: cdecl is your friend: int a[2][3], int (*q)[2][3].

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
6

The [3] is a part of the type. In this case p is a pointer to an array of size 3 which holds ints.

The particular type of an array always includes its size, so that you have the types int *[3] or int *[5], but not just int *[] which has undefined size.

int *x[20]; /* type of x is int *[20], not just int *[] */
int y[10][10]; /* type of y is int[10][10], not just int[][] */
Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • Thanks for your comment. When you say size, does it mean (*p) has [0],[1]],[2] ? If this is the case, where is a room for [2]? Or does it points to [0][0] and [0][1]? – user1047092 Dec 23 '11 at 15:11
  • `p` is simply a pointer to an array of 3 ints. It doesn't know that the first dimension of `a` is 2, because it is assigned to the first element of `a`, which is exactly of type `int[3]`. – Blagovest Buyukliev Dec 23 '11 at 15:17
3

Also note:

int *p[5]        // p is an array of 5 pointers

int (*p)[5]      // p points to an array of 5 ints

int (*(p+5))[10] // p is a pointer to a structure where the structure's 5th element has 10 ints .
MarianD
  • 13,096
  • 12
  • 42
  • 54
sdinesh94
  • 1,138
  • 15
  • 32
  • The OP asks a conceptual question and I have answered it here. In place of 5 put 3!. Also I have added more details on how to obtain value from 2d arrays using pointers. – sdinesh94 Oct 25 '15 at 20:32
  • I would argue that this is more confusing than the rest of the answers provided here. – rayryeng Oct 25 '15 at 20:38
3

you can point to 2d array like 1d array

#include <iostream>
int main()
{
   int array[2][2] = {{0,1}, {2,3}}; // array
   int *ptr;
   ptr=(int*)array;
   std::cout << *(ptr)   << '\n';//out 0
   std::cout << *(ptr+1) << '\n';//out 1 
   std::cout << *(ptr+2) << '\n';//out 2
   std::cout << *(ptr+3) << '\n';//out 3
}