0

I have a question about syntax of pointer to arrays. Well we know arrays are pointers themselves(what our uni professor said) so why when we point to them with another pointer (which would be a pointer to pointer) we use this syntax:

int array[10]; 
int *pointer = array;

Instead of this syntax:

int array[10];
int **pointer = &array;

Although i know this would be correct using malloc but why not in the normal way, is it a compiler or syntax thing or i am wrong somewhere else??

  • 1
    Array-to-pointer is a **conversion**. Saying arrays are pointers makes as much sense as saying `double`s are `int`s because you can go `int x = 5.5;` . In fact it is a lossy conversion just like double->int, because you lose the length of the array. – M.M Mar 01 '15 at 05:11
  • 5
    _"Well we know arrays are pointers themselves"_ No no no no no no no no **no** – Lightness Races in Orbit Mar 01 '15 at 05:17

3 Answers3

5

Tell your professor they are wrong. Arrays are not pointers. Arrays can decay to pointers, but they are not pointers.

int* pointer = array; declares a pointer that points to the first element in array.

int** pointer = &array; is not correct. As mentioned by jschultz410 in the comments, the type of &array is not int**, it is int (*)[10] aka a pointer to an array of 10 ints, which cannot decay to int**.

Community
  • 1
  • 1
emlai
  • 37,861
  • 9
  • 87
  • 140
  • Because the type of &array is actually int (*)[10]. In C++ you need a cast. In C, you can probably skate by with a warning. – jschultz410 Mar 01 '15 at 05:00
  • 1
    Also, it's not actually pointing to a pointer pointing to the first element in array. It is still pointing at the first element of array, it just requires two dereferences to get an int out of it. – jschultz410 Mar 01 '15 at 05:07
  • *Your assumption that "arrays are pointers themselves" is not entirely correct.* It is in fact entirely incorrect. – Keith Thompson Mar 01 '15 at 05:43
  • @KeithThompson Edited that. – emlai Mar 01 '15 at 05:49
3

Well we know arrays are pointers themselves

No. Arrays are not pointers. Arrays are arrays. Except when it is the operand of the sizeof or the unary & operator, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer toT" and the value of the expression will be the address of the first element of the array. However, no storage is set aside for a pointer in addition to the array elements themselves.

So, given the declaration

int array[10];

the type of the expression array is "10-element array of int"; unless array is the operand of sizeof or unary &, it will decay to type int *. So

int *ptr = array;

works.

The type of &array is not int **; the type is int (*)[10], or "pointer to 10-element array of int". You'd declare and initialize such a pointer as

int (*ptr)[10] = &array;
John Bode
  • 106,204
  • 16
  • 103
  • 178
3

First of all this definition of a pointer

int array[10]; 
int **pointer = &array;

is invalid. In the right side of the declaration there is an expression having type int ( * )[10] while in the left side there is identifier of type int **. There is no implicit conversion between pointers int ( * )[10] and int ** . So the compiler shall issue a diagnostic message.

The correct definition will look

int array[10]; 
int ( *pointer )[10] = &array;

Now we can consider what is the difference between these two definitions

int array[10]; 
int *pointer = array;

and

int array[10]; 
int ( *pointer )[10] = &array;

In the first case the size of the object pointed to by pointer pointer is equal to sizeof( int ). So if to use the pointer arithmetic then after evaluation of expression ++pointer the value in the pointer will be increased by sizeof( int ) bytes. If for example sizeof( int ) is equal to 4 then the value in the pointer will be increased by 4.

In the second case the size of the object pointed to by pointer pointer is equal to 10 * sizeof( int ) that is if sizeof( int ) is equal to 4 then the size of the object is equal to 40. So if the pointer will be increased ++pointer its value will be increased by 40.

Also dereferencing the pointer in the first case will give you an object of type int while dereferencing the pointer in the second case will give you an object of type int[10] that is an array.

And arrays are not pointers. Simply they are usually converted to pointers to their first elements in expressions. From the C Standard

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

If you write for example

int array[10]; 
int *pointer = array;

then sizeof( array ) is not equal to sizeof( pointer ) though you can use the common syntax to access elements of the array:

array[ i ] and pointer[ i ] and will get the same result..

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268