Using a pointer to point to a certain row in c

Viewed 93

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}};
4 Answers

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
  • A 2D array in C is an array of arrays.
  • double a[2][4] = an array with size 2, each items of type double[4].
  • A pointer to such an array is declared as double (*p)[2][4] and initialized/assigned as p=&a.
  • Similarly, a pointer to an array of type double a[4] is declared as double (*p)[4].
  • Any array in C, whenever used in most expressions, "decays" into a pointer to its first element.
  • Since the first item of 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) );
}
Related