2-D Arrays with pointers

2-D arrays with pointers allow a programmer to easily navigate and manage a large number of elements. This chapter explains the memory layout of a 2-D array and demonstrates how to access that memory using pointers, breaking down a complex concept into easy-to-understand techniques.

2-D array addressing and dereferencing

Let’s take a 2-D array int arr[5][7];.

1. Traversing from One 1-D Array (Row) to Another:
  • The array name arr represents the first 1-D array (row 0).
  • arr + 1 represents the second 1-D array (row 1).
  • arr + 2 represents the third 1-D array (row 2).
  • Therefore, arr + i represents the i-th row.
2. Traversing Through Columns and Rows:
  • *(arr + i) dereferences to the i-th row.
    • *(arr) points to the 0th element in the first 1-D array (row 0).
    • *(arr + 1) points to the 0th element in the second 1-D array (row 1).
    • *(arr + i) points to the 0th element (column 0) in the i-th row.
  • To access specific columns within a row:
    • *(arr + i) + 1 points to the second element (column 1) in row i.
    • *(arr + i) + j points to the j-th column in the i-th row.
3. Accessing an Element in a 2-D Array:
  • As mentioned earlier, *(arr + i) + j points to the j-th column in the i-th row.
  • To access the value at this position (i-th row and j-th column), you need to dereference the pointer:
    • *(*(arr + i) + j) will give the value at the j-th column in the i-th row of the 2-D array.
Program to illustrate 2-D array addressing and dereferencing
#include <stdio.h>

int main()
{
        int arr[3][6] = {
                {23, 44, 66, 12, 1},
                {101, 15, 16, 98},
                {77}
        };
        int i, j;

        /* traverse through rows */
        for (i = 0; i < 3; i++) {
                printf("row %d elements are: ", i);
                 /* traverse through columns */
                for (j = 0; j < 6; j++) {
                        printf("%d ", *(*(arr + i) + j));
                }
                printf("\n");
        }
}

output

row 0 elements are: 23 44 66 12 1 0 
row 1 elements are: 101 15 16 98 0 0 
row 2 elements are: 77 0 0 0 0 0 

Array of Pointers

In the 1-D arrays chapter, we learned that arrays are collections of elements of the same type. However, we didn’t explore the concept of maintaining an array of pointers. Pointers hold the address of a variable, and we’ve seen how a single pointer, like int *ptr, can be used to traverse a 1-D array. But when it comes to traversing a 2-D array, additional considerations are necessary, one of which is using an array of pointers.

An array of pointers can be declared as follows:

int *ptr[10];

Here, ptr is an array containing 10 pointers, each pointing to an integer.

Each pointer in the array can be assigned to a 1-D array, and collectively, the array of pointers can be used to traverse a 2-D array, as demonstrated in the program below.

#include <stdio.h>

int main()
{
        int arr[3][6] = {
                {23, 44, 66, 12, 1},
                {101, 15, 16, 98},
                {77}
        };
        int i, j;
        int *ptr[3];

        ptr[0] = *arr;   // assigning 1st 1-D array
        ptr[1] = *(arr + 1);  // assigning 2nd 1-D array
        ptr[2] = *(arr + 2);  // assigning 3rd 1-D array

        for (i = 0; i < 3; i++) {
                printf("row %d elements are: ", i);
                for (j = 0; j < 6; j++) {
                        printf("%d ", ptr[i][j]);
                }
                printf("\n");
        }
}

output

row 0 elements are: 23 44 66 12 1 0 
row 1 elements are: 101 15 16 98 0 0 
row 2 elements are: 77 0 0 0 0 0 

However, an array of pointers can be difficult to maintain and use in some cases, as each pointer must be individually assigned to a 1-D array to represent a 2-D array. To simplify traversing 2-D array elements, the concept of a pointer to an array can be used. This approach makes it easier to manage and access the elements of a 2-D array.

Pointer to an Array

An array of pointers can hold the addresses of elements in an array, but it doesn’t have information about the number of elements in each array. But a pointer to an array is aware of the number of elements (or columns) in each array. A pointer to an array can be declared as follows:

int (*ptr)[10];

This declaration means that ptr is a pointer to an array of 10 integer elements.

Program to illustrate array of pointers

#include <stdio.h>

int main()
{
        int arr[3][6] = {
                {23, 44, 66, 12, 1},
                {101, 15, 16, 98},
                {77}
        };
        int i, j;
        int (*ptr)[6] = arr;


        while ((ptr - arr) < 3) {
                for (j = 0; j < 6; j++) {
                        printf("%d ", (*ptr)[j]);
                }
                printf("\n");
                ptr++;
        }
}

output

23 44 66 12 1 0 
101 15 16 98 0 0 
77 0 0 0 0 0 

As you can see, when ptr++ is executed, ptr moves to the next 1-D array because it is a pointer to an array.