вторник, 10 августа 2010 г.

Array name != pointer to the first array element?

from the standard (4.2.1):
An lvalue or rvalue of type 'array of N T' or 'array of unknown bound of T' can be converted to an rvalue of type 'pointer to T'. The result is a pointer to the first element of the array.
I.e.:
An Array variable, defined as
T ar[N];  //array of N T
or
T ar[] = {val1, val2, val3}; //array of unknown bound of T
can be converted to an rvalue of type 'pointer to T'

Let's assume we have an array:
int ar[10];
if we want to pass it to a function
void Foo(int* ar);
we should write next:
Foo(ar); // ar automatically converted to a pointer to the 1st element
Or
int ar[10];
int* p = ar;
*p = 10; // equals ar[0] = 10;
p+=2;
*p = 20; // equals ar[2] = 20;
We can also write the next:
int (*p)[10];
Here p is a pointer to array of 10 int's (type is int (*)[10]). Exactly "pointer to array"!
In this case the expression
p = ar;
won't compile. In the declaration
int (*p)[10];
p is already a pointer(!),
thus if ar[10] is an array, and ar is a pointer, then if (*p)[10] is a pointer,
and p is a pointer to pointer
So we should write the next:
p = &ar;
Despite ar and &ar have the same meaning.
since p is associated with 10 int's array, then while incrementing
p will change to sizeof(int), rather than 10*sizeof(int).
int ar[3][4];
for(int i=0; i < 3; i++)
{
    for (int j=0; j < 4; j++)
    {
        ar[i][j]=i+j;
    }
} 
int (*p)[4];
p=ar;
++p; //advance to the next row
int a_2_1 = *(*(p+2)+1) // equals int a_2_1 = p[2][1]