Here we are discussing pointers and 2D array. While we are discussing the 2D array, the representation of the 2D array is in matrix form. Example:
int arr[3][4] = {
{11,22,33},
{55,66,77},
{11,88,99}
};
The 2D array can be visualized in matrix form:
COL 0 COL 1 Col 2
ROW 0 11 22 33
ROW 1 55 66 77
ROW 2 11 88 99
We use terminology like rows and columns when talking about arrays. Because computer memory is linear and does not have rows and columns, this concept is just theoretical. So, how are 2-D arrays truly kept in memory? Arrays are stored in C in row-major order. This simply means that row 0 is saved first, followed by row 1, row 2, and so on.
The following representation shows a 2D array in memory:
0-th 1-st 2-nd
1D Array 1D Array 1D Array
==============|==============|=============
11 22 33 55 66 77 11 88 99
100 104 108 112 114 116 120 124 128
Here is the most important concept you need to remember in the multi-dimensional array:
A 2-D array is actually a 1-D array in which each element is itself a 1-D array. So arr is an array of 3 elements where each element is a 1-D array of 3 integers.
Important
In this case, of a 2D array, the 0th element is a 1D array. As a result, the type or base type of arr in the above example is a pointer to an array of four integers. Because pointer arithmetic is done in terms of the pointer’s base size. If arr points to address 2000, then arr + 1 points to address 2016 (i.e. 2000 + 3*4) in the case of arr.
We know that the array’s name is a constant pointer pointing to the array’s 0th element. The 0th element in a two-dimensional array is a one-dimensional array. In the case of a 2-D array, the array name is a pointer to the 0th 1-D array. As a result, arr is a pointer to a four-element array in this situation. If the address of the 0th 1-D is 2000, then (arr + 1) represents the address 2012, and (arr + 2) represents the address 2028, according to pointer arithmetic.
From the above discussion, we can conclude that:
arr
points to 0th 1-D array.(arr + 1)
points to 1st 1-D array.(arr + 2)
points to the 2nd 1-D array.
arr => 11 22 33
arr + 1 => 55 66 77
arr + 2 => 11 88 99
We can write the following in general:
(arr + i) is the index of the ith 1-D array.
Dereferencing a pointer to an array returns the array’s base address, as we discussed earlier in this chapter. Dereferencing arr yields arr, whose base type is (int). Similarly, when we decode (arr+i) we get *(arr+i). In general, we can state the following:
The base address of the ith 1-D array is pointed to by *(arr+i).
It’s worth noting that while type (arr + i) and *(arr+i) both refer to the same address, their basic types are completely different. (arr + i) is a pointer to a three-int array, whereas *(arr + i) is a pointer to int or (int*).
So, how can you access individual items in a 2-D array using arr?
We should be able to access elements of ith 1-D array using pointer arithmetic because *(arr + i) points to the base address of every ith 1-D array and is of base type pointer to int.
Let’s have a look at how we can accomplish this:
The address of the
0th element of the 1-D array is pointed to by *(arr + i). As a result, *(arr +i) + 1 denotes the address of the 1-D array’s first element. *(arr + i) + 2 is the address of the 1-D array’s second element.
As a result, we can deduce that:
*(arr + i) + j points to the base address of the ith 1-D array’s jth element.
We may get the value of the jth element of the ith 1-D array by dereferencing *(arr + i) + j.
*( *(arr + i) + j)
We can obtain the value of the jth element of the ith 1-D array using this expression.
Furthermore, the subscript notation is equal to the pointer notation *(*(arr + i )+ j).
The following program shows how to use pointer notation to retrieve the values and addresses of elements in a 2-D array.
#include<stdio.h> int main() { int arr[3][4] = { {11,22,33}, {55,66,77}, {11,88,99} }; int i, j; for(i = 0; i < 3; i++) { printf("Address of %d th array %u \n",i , *(arr + i)); for(j = 0; j < 4; j++) { printf("arr[%d][%d]=%d\n", i, j, *( *(arr + i) + j) ); } printf("\n\n"); } // signal to operating system program ran fine return 0; }
Output:
Address of 0 th array 2686736
arr[0][0]=11
arr[0][1]=22
arr[0][2]=33
Address of 1 th array 2686752
arr[1][0]=55
arr[1][1]=66
arr[1][2]=77
Address of 2 th array 2686768
arr[2][0]=11
arr[2][1]=88
arr[2][2]=99
Assigning 2-D Array to a Pointer Variable
You can assign the array’s name to a pointer variable, however, unlike with a 1-D array, you’ll require a pointer to an array rather than a pointer to int or (int *). Here’s an illustration:
int arr[2][3] = {
{33, 44, 55},
{11, 99, 66}
};
Always keep in mind that a 2-D array is a 1-D array with each element being a 1-D array. As a result, arr is a two-element array with each element being a one-dimensional arr of three integers. As a result, you’ll need a pointer to an array of 3 integers to store arr’s base address.
Similarly, if a 2-D array includes three rows and four columns, such as int arr[3][4], you’ll need a pointer to a four-int array.
int (*p)[3];
Here, p is a pointer to a three-int array. So, according to pointer arithmetic, p+i corresponds to the ith 1-D array, whereas p+0 corresponds to the 0th 1-D array, p+1 to the 1st 1-D array, and so on. (p+i) has a pointer to a three-int array as its base type. We can access the base address of ith 1-D array if we dereference (p+i), but now the base type of *(p + i) is a pointer to int or (int *). To get the address of the jth element of the ith 1-D array, simply add j to *(p +i) as a result, *(p +i) + j denotes the address of the jth element of the ith 1-D array.
The following program demonstrates how to access elements of a 2-D array using a pointer to an array.
#include<stdio.h> int main() { int arr[3][3] = { {11,22,33}, {55,66,77}, {11,88,99} }; int i, j; int (*p)[3]; p = arr; for(i = 0; i < 3; i++) { printf("Address of %d th array %u \n",i , p + i); for(j = 0; j < 4; j++) { printf("arr[%d][%d]=%d\n", i, j, *( *(p + i) + j) ); } printf("\n\n"); } // signal to operating system program ran fine return 0; }
Expected Output:
Address of 0 th array 2686736
arr[0][0]=11
arr[0][1]=22
arr[0][2]=33
Address of 1 th array 2686752
arr[1][0]=55
arr[1][1]=66
arr[1][2]=77
Address of 2 th array 2686768
arr[2][0]=11
arr[2][1]=88
arr[2][2]=99