If I have array a
, how would I set a pointer to the first row?
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
If I have array a
, how would I set a pointer to the first row?
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
You can declare a pointer to a row and initialize it to point to the first row with the following line:
double (*p_first_row)[4] = &a[0];
Due to array to pointer decay, you can also write:
double (*p_first_row)[4] = a;
The parentheses are necessary, because the declaration
double *p[4];
declares an array of pointers, whereas the declaration
double (*p)[4];
declares a pointer to an array.
If you have a multi-dimensional array like for example
T a[N1][N2][N3][N4];
where T
is some type specifier and N1
, N2
, N3
, N4
are some positive integers then to make a pointer to the first element of the array just change the left most dimension to asterisk like
T ( *p )[N2][N3][N4] = a;
In this declaration the array designator a
is implicitly converted to a pointer to its first element.
If you want to get a pointer to the i-th (0 <= i < N1
) element of the array (that is an array of the type T[N2][N3][N4]
) you can write
T ( *p )[N2][N3][N4] = a + i;
or
T ( *p )[N2][N3][N4] = a;
p += i;
Here is a demonstration program.
#include <stdio.h>
int main( void )
{
double a[2][4] =
{
{1, 2, 3, 4},
{5, 6, 7, 8}
};
for ( double ( *row )[4] = a; row != a + 2; ++row )
{
for ( double *p = *row; p != *row + 4; ++p )
{
printf( "%.1f ", *p );
}
putchar( '\n' );
}
}
The program output is
1.0 2.0 3.0 4.0
5.0 6.0 7.0 8.0
Just dereference it normally as you would do to any pointer.
*(a + 0)
gives you the first row of the matrix, and *(a + i)
will give you the i-th
row in the 2D array.
A sample code to get the first element in each row of your 2d array would look like this.
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
for (int i = 0; i < 2; i ++) {
printf("%lf ", *(a + i)[0]);
}
Output:
1 5
double a[2][4]
= an array with size 2, each items of type double[4]
.double (*p)[2][4]
and initialized/assigned as p=&a
.double a[4]
is declared as double (*p)[4]
.double a[2][4]
has type double [4]
, then a
will decay into a pointer to such an item, double (*)[4]
, whenever used in an expression.Therefore we can iterate through the double a[2][4]
like this, if we wish:
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
for(double (*p)[4]=a; p<a+2; p++)
{
printf("%lf %lf %lf %lf\n", (*p)[0],(*p)[1],(*p)[2],(*p)[3]);
}
Which is also equivalent to double (*p)[4]=&a[0]
.
Now suppose that we write an expression some with saner syntax as we ought to:
a[i][j]
Any a[i]
expression is by definition 100% equivalent to *(a+i)
. So the above is equivalent to *(*(a+i)+j)
.
Here pointer arithmetic is used twice: a+i
is pointer arithmetic on a double(*)[4]
type, increasing the address with i * sizeof(double[4])
bytes. Whereas the +j
part is pointer arithmetic on a double*
, increasing the address with j * sizeof(double)
bytes.
Thus a[1][0]
= (char*)a + 1 * sizeof(double[4]) + 0 * sizeof(double)
Example:
#include <stdio.h>
int main()
{
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
printf("%lf ", a[1][0] );
printf("%lf ", (char*)a + 1 * sizeof(double[4]) + 0 * sizeof(double) );
}