问题
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:
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;
回答2:
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**
.
回答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..
来源:https://stackoverflow.com/questions/28790204/pointer-to-arrays-syntax