This declaration
char (*p_arr)[1] = &arr;
is incorrect because the declared pointer and the initializer have incompatible types. There is no implicit conversion from the type char ( * )[5]
, the type of the initializer, to the type char ( * )[1]
, the ty[e of the declared pointer. So you need an explicit casting to reinterpret a pointer of one type as a pointer of another type as for example
char (*p_arr)[1] = ( char ( * )[1] )&arr;
As for your question then if you have an object of type T
where T
is some type
T obj;
and a pointer to the object like
T *ptr = &obj;
then expression *ptr
or ptr[0]
yields the referenced object of the type T
.
So let's assume that you have the following declarations
char arr[5] = {'A', 'E', 'I', 'O', 'U'};
char (*p_arr)[5] = &arr;
For the type char[5]
that is the type of the variable arr
you can introduce a typedef name.
typedef char T[5];
Then the declarations will look like
T arr = {'A', 'E', 'I', 'O', 'U'};
T *p_arr = &arr;
As it was mentioned above the expression *p_arr
or p_arr[0]
yields the referenced object of the type T
that is of the type char[5]
.
From the C Standard (6.5.3.2 Address and indirection operators)
4 The unary * operator denotes indirection. If the operand points to a
function, the result is a function designator; if it points to an
object, the result is an lvalue designating the object. If the operand
has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
invalid value has been assigned to the pointer, the behavior of the
unary * operator is undefined.
And (6.5.2.1 Array subscripting)
2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).
and at last (6.5.6 Additive operators)
7 For the purposes of these operators, a pointer to an object that
is not an element of an array behaves the same as a pointer to the
first element of an array of length one with the type of the object as
its element type.
So in this declaration
char arr[5] = {'A', 'E', 'I', 'O', 'U'};
char (*p_arr)[5] = &arr;
the pointer p_arr
does not point to an array element. However it can behaves as it points to the first element of an array of length 1. You can imagine it the following way
char arr[1][5] = { {'A', 'E', 'I', 'O', 'U'} };
char (*p_arr)[5] = arr;
So the expression p_arr[0]
gives the first element of the imagined two-dimensional array that is an element of the type char[5]
.