In my C program book, I meet the question about (*p)[num2]
there is a 2 dimension array named a[num1][num2]
and a (*p)[num2]
next,in the statement
for(p=&a[0];p<&a[num1];p++)
(*p)[i]=0;
that statement will make the 2 dimension array's i column assign 0
but i don't understand why (*p)[num2]
point to a
's row,I think create *p
and p=&a[num1]
can do that,too.
and,why p++
point to next row but not the next value behind a[num][i]
why?,i have understand the difference between *p[3]
and (*p)[3]
I think *p could point to an array(first address) why used (*p)[num] to point array.
Let's start from providing a useful quote from the C standard relative to arrays and implicit conversions (6.3.2.1 Lvalues, arrays, and function designators)"
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.
So if for example you have an array like that
int a[num1][num2];
then used in expressions with rare exceptions mentioned in the quote it is implicitly converted to a pointer to its initial element.
Elements of the two-dimensional array a
are in turn arrays of the type int[num2]
. A pointer to the element type of the array has type int ( * )[num2]
. You may declare a corresponding pointer the following way
int ( *p )[num2] = a;
that is the same as
int ( *p )[num2] = &a[0];
Now the pointer p
points to the first "row" of the two-dimensional array a
. After incresing it using the prefix increment operator ++p
or postfix increment operator p++
it will point to the next (second) element (row) of the type int[num2]
of the array a
. Dereferencing the pointer like *p
you will get the one-dimensional array (row) of the type int[num2]
pointed to by the pointer. And to apply to the resulted expression the subscript operator like ( *p )[i]
you will get the i-th
element of the current row of the array a
.
On the other hand, if you have
int ( *p )[num2] = a;
then the expression p + num1
will point to the memory after the last element (one-dimensional array of the type int[num2]
) of the array a
. The expression p + num1
is equivalent to the expression a + num1
(due to the implicit conversion of the array a
to a pointer to its initial element) that in turn is equivalent to the expression &a[num1]
. According to the last expression there is written in the C Standard (6.5.3.2 Address and indirection operators)
3 The unary & operator yields the address of its operand. If the operand has type "type", the result has type "pointer to type". If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a+ operator. Otherwise, the result is a pointer to the object or function designated by its operand.
So as it follows from the quote the expression &a[num1]
is equivalent to the expression a + num1
.
Thus this for loop
for ( p = &a[0]; p < &a[num1]; p++ )
( *p )[i] = 0;
may be rewritten like
for ( p = a; p < a + num1; p++ )
( *p )[i] = 0;
As for the subscript operator then (the C Standard, 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).
Thus this expression statement in the body of the for loop
( *p )[i] = 0;
may be also rewritten like
*( *( p + 0 ) + i ) = 0;
or like
*( *p + i ) = 0;