2

For instance,

int array[5] = {1}: // array of 5 integers
int (*ptr)[5] = &array; // pointer to an array of 5 integers

The following have the same value:

*ptr;
ptr;

If I were to call printf("%p, %p", *ptr, ptr); both outputs would be exactly the same. Why is this?

user50449
  • 91
  • 5
  • 1
    Read section 6 of the [comp.lang.c FAQ](http://www.c-faq.com/). – Keith Thompson Jan 02 '15 at 21:04
  • 3
    @inetknght: It is declared and initialized in the second line of code. – AnT stands with Russia Jan 02 '15 at 21:07
  • 1
    This question has been asked many times. In both C and C++, array names "decay" to pointers: http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c. This line `int (*ptr)[5] = &array` both declares and initializes the variable "ptr". – FoggyDay Jan 02 '15 at 21:07
  • Note, however, that `*ptr + 1` and `ptr + 1` have different values because the types are different. – Jonathan Leffler Jan 02 '15 at 21:12
  • The possible duplicate question (http://stackoverflow.com/q/1641957) does not mention `&array`, and the top answer does not discuss `&array`, which makes it not a duplicate. Related, certainly; duplicate, no. – Jonathan Leffler Jan 02 '15 at 21:15

3 Answers3

2

In this statement

int (*ptr)[5] = &array;

pointer ptr is initialized by the address of the array. The address of the array is the address of its first element that is of the first row.

Expression

*ptr;

gives you reference to this first element that is to the one-dimensional array - the first row or more precisely to the original array..

In turn in expressions arrays are converted to pointers to their first elements and *ptr that is equivalent to expression array is converted to rvalue of type pointer that points to the first element of array *ptr.:) That is expression *ptr will have type int * The address of the first row and the address of the first element of the first row is the same. Now you have two pointers, ptr and *ptr the first one has type int ( * )[5] while the second one has type int * but the both have the same value.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

If you look at the memory layout of a 1D array such as

int array[5];

it will make sense.

        array
          |
          V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

  array[0]
  |
  V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

Address of array
|
V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

Address of array[0]
|
V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

i.e. &array == &array[0] == array decayed to a pointer

With a pointer declared as:

int (*ptr)[5] = &array;

ptr == &array
*ptr == array decayed to a pointer == &array[0] == &array

That's why you see the same value printed when you use:

printf("%p, %p", *ptr, ptr);
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Since printf is a variadic function, the ellipsis conversion sequences are applied to the arguments. In particular, arrays are decayed to a pointer of the underlying type : IOW, it is implicitly converted to a pointer to the first element of the array. Thus, when you call printf("%p, %p", *ptr, ptr);, *ptr, which is of type int[5] is converted to an int* with value &array[0].

Pradhan
  • 16,391
  • 3
  • 44
  • 59