Programming in C: Unit III (b): Pointers

Pointers and 2D Arrays

with Example C Programs

Elements of a two-dimensional array are stored in contiguous memory locations. A two-dimensional array is not the same as an array of pointers to one-dimensional arrays.

POINTERS AND 2D ARRAYS

Elements of a two-dimensional array are stored in contiguous memory locations. A two-dimensional array is not the same as an array of pointers to one-dimensional arrays. To declare a pointer to a two-dimensional array, you may write

int **ptr;

Here int **ptr is an array of pointers (to one- dimensional arrays), while int mat [5] [5] is a 2D array. They are not the same type and are not interchangeable. Consider a two-dimensional array declared as

int mat [5] [5];

Individual elements of the array mat can be accessed using either:

mat [i] [j] or

*(*(mat + i) + j) or

* (mat [i]+j);

To understand more fully what is going on, let us replace

*(multi+row) with X so the expression

* (* (mat + i) + j) becomes * (X + col)

Using pointer arithmetic, we know that the address pointed to by (i.e., value of) x + col + 1 must be greater than the address X + col by an amount equal to sizeof (int).

Since mat is a two-dimensional array, we know that in the expression multi + row as used above, multi + row + 1 must increase in value by an amount equal to that needed to point to the next row, which in this case would be an amount equal to COLS* sizeof(int).

Thus, in case of a two-dimensional array, in order to evaluate expression (for a row major 2D array), we must know a total of 4 values:

1. The address of the first element of the array, which is given by the name of the array, i.e., mat in our case

2. The size of the type of the elements of the array, i.e., size of integers in our case

3. The specific index value for the row

4. The specific index value for the column

Note that

int (*ptr) [10];

declares ptr to be a pointer to an array of 10 integers. This is different from

int *ptr [10];

which would make ptr the name of an array of 10 pointers to type int. You must be thinking how pointer arithmetic works if you have an array of pointers. For example:

int * arr [10]

int ** ptr = arr ;

In this case, arr has type int **. Since all pointers have the same size, the address of ptr + i can be calculated as:

addr (ptr + i) = addr (ptr) + [sizeof (int *) * i] = addr (ptr) + [2 * i]

Since arr has type int **

arr [0] =&arr [0] [0],

arr [1] = &arr [1] [0], and in general,

arr[i] = &arr [i] [0].

According to pointer arithmetic, arr + i = & arr[i], yet this skips an entire row of 5 elements, i.e., it skips complete 10 bytes (5 elements each of 2 bytes size). Therefore, if arr is address 1000, then arr + 2 is address 1010. To summarize, &arr [0] [0], arr[0], arr, and &arr [0] point to the base address.

&arr[0][0] + 1 points to arr[0] [1]

arr[0] + 1 points to arr[0] [1]

arr + 1 points to arr [1] [0]

&arr [0] + 1 points to arr [1] [0]

To conclude, a two-dimensional array is not the same as an array of pointers to ID arrays. Actually a two- dimensional array is declared as:

int (*ptr) [10] ;

Here ptr is a pointer to an array of 10 elements. The parentheses are not optional. In the absence of these parentheses, ptr becomes an array of 10 pointers, not a pointer to an array of 10 ints.

Note

Pointer to a one-dimensional array can be declared as

int arr[]={1,2,3,4,5);

int *parr;

parr = arr;

Similarly, pointer to a two-dimensional array can be declared as

int arr[2] [2]={{1,2}, {3, 4}};

int (*parr) [2];

parr = arr;

Look at the code given below which illustrates the use of a pointer to a two-dimensional array.

#include <stdio.h>

main ()

{

int arr [2] [2]={{1,2}. {3, 4}};

int i, (*parr) [2];

parr = arr;

for (i 0; i < 2; i++)

{

for (j = 0; j < 2 ;j++)

printf("%d", (* (parr+i)) [j]);

}

}

Output

1 2 3 4

The golden rule to access an element of a two- dimensional array can be given as

arr[i][j] = (* (arr+i)) [j] = *((*arr+i))+j) = * (arr[i]+j)

Therefore,

arr [0] [0] = *(arr) [0] = *((*arr) +0) =*(arr [0] +0)

arr [1] [2] = (* (arr+1)) [2] = *((* (arr+1))+2) = * (arr [1]+2)

If we declare an array of pointer using

data_type *array_name [SIZE];

Here SIZE represents the number of rows and the space for columns that can be dynamically allocated.

If we declare a pointer to an array using,

data_type (*array_ name) [SIZE];

Here SIZE represents the number of columns and the space for rows that may be dynamically allocated.

29. Write a program to read and display a 3 x 3 matrix.

#include <stdio.h>

int main()

{

int i, j, mat [3] [3];

clrscr();

printf("\n Enter elements of the matrix");

printf("\n ****************");

for (i=0;i<3;i++)

{

for(j=0;j<3;j++)

{

printf("\n mat [%d] [%d] = ",i,j);

scanf("%d", &mat [i] [j]);

}

}

printf("\n Elements of the matrix are");

printf("\n **********");

for (i=0;i<3; i++)

{

printf("\n");

for(j = 0; j < 3; j++)

printf("\t mat [%d] [%d] = %d", i,j,* (* (mat + i)+j));

}

return 0;

}

OR

#include <stdio.h>

int main()

{

int i, j, mat [3] [3];

clrscr();

printf("\n Enter elements of the matrix");

printf("\n ***************" ) ;

for (i=0;i<3; i++)

{

for(j=0;j<3;j++)

{

printf("\n mat [%d] [%d] = ",i,j);

scanf("%d", (* (mat + i)+j);

}

}

printf("\n The elements of the matrix are ");

printf("\n **:************") ;

for (i=0;i<3;i++)

{

printf("\n");

for(j=0;j<3;j++)

printf("\t mat [%d] [%d] = %d", i, j,*(* (mat + i)+j);

}

return 0;

}

OR

#include <stdio.h>

void display (int (*) [3]);

int main()

{

int i, j, mat [3] [3];

clrscr();

printf("\n Enter elements of the matrix");

printf("\n **************") ;

for (i=0;i<3; i++)

{

for(j = 0; j < 3; j++)

{

printf("\n mat [%d] [%d] = ",i,j);

scanf("%d", &mat [i] [j]);

}

}

display (mat);

}

void display (int (*mat) [3])

{

int i, j;

printf("\n elements of the matrix are");

printf("\n ***************");

for (i = 0; i < 3; i++)

{

printf("\n");

for(j=0;j<3;j++)

printf("\t mat [%d] [%d] = %d", i,j,*(* (mat + i)+j));

}

return 0;

}

Output

Enter the elements of the matrix

*************************

1 2 3 4 5 6 7 8 9

The elements of the matrix

*************************

1 2 3

4 5 6

7 8 9

Note

A double pointer cannot be used as a 2D array. Therefore, it is wrong to declare: 'int **mat' and then use 'mat' as a 2D array. These are two very different data types used to access different locations in memory. So running such a code may abort the program with a ‘memory access violation' error.

A 2D array is not equivalent to a double pointer. A 'pointer to pointer of T' can't serve as a '2D array of T'. The 2D array is equivalent to a pointer to row of T, and this is very different from pointer to pointer of T.

When a double pointer that points to the first element of an array is used with the subscript notation ptr[0][0], it is fully dereferenced two times and the resulting object will have an address equal to the value of the first element of the array.

Programming in C: Unit III (b): Pointers : Tag: : with Example C Programs - Pointers and 2D Arrays