Wednesday, November 2, 2011

Pointers and 2-Dimensional Arrays in C programming language

The C language embodies an unusual but powerful capability—it can treat parts of arrays as arrays. More specifically, each row of a two-dimensional array can be thought of as a one-dimensional array. This is a very important fact if we wish to access array elements of a two-dimensional array using pointers. Thus, the declaration,

int  s[5][2] ;

can be thought of as setting up an array of 5 elements, each of which is a one-dimensional array containing 2 integers. We refer to an element of a one-dimensional array using a single subscript. Similarly, if we can imagine s to be a one-dimensional array then we can refer to its zeroth element as s[0], the next element as s[1] and so on. More specifically, s[0] gives the address of the zeroth one-dimensional array, s[1] gives the address of the first one-dimensional array and so on. This fact can be demonstrated by the following program.

/* Demo: 2-D array is an array of arrays */
main( )
{
      int  s[4][2] = {
     { 1234, 56 },
     { 1212, 33 },
     { 1434, 80 },
     { 1312, 78 }
                       } ;
      int  i ;

      for ( i = 0 ; i <= 3 ; i++ )
            printf ( "\nAddress of %d th 1-D array = %u", i, s[i] ) ;
}

And here is the output...

Address of 0 th 1-D array = 65508
Address of 1 th 1-D array = 65512
Address of 2 th 1-D array = 65516
Address of 3 th 1-D array = 65520

Let’s figure out how the program works. The compiler knows that s is an array containing 4 one-dimensional arrays, each containing 2 integers. Each one-dimensional array occupies 4 bytes (two bytes for each integer). These one-dimensional arrays are placed linearly (zeroth 1-D array followed by first 1-D array, etc.). Henceeach one-dimensional arrays starts 4 bytes further along than the last one, as can be seen in the memory map of the array shown below.


We know that the expressions s[0] and s[1] would yield the addresses of the zeroth and first one-dimensional array respectively. From Figure 8.6 these addresses turn out to be 65508 and 65512. Now, we have been able to reach each one-dimensional array. What remains is to be able to refer to individual elements of a one-dimensional array. Suppose we want to refer to the element s[2][1] using pointers. We know (from the above program) that s[2] would give the address 65516, the address of the second one-dimensional array. Obviously ( 65516 + 1 ) would give the address 65518. Or  ( s[2] + 1 ) would give the address 65518. And the value at this address can be obtained by using the value at address operator, saying *( s[2] + 1 ). But, we have already studied while learning one-dimensional arrays that num[i] is same as *( num + i ). Similarly, *( s[2] + 1 ) is same as, *( *( s + 2 ) + 1 ). Thus, all the following expressions refer to the same element,

s[2][1]
* ( s[2] + 1 )
* ( * ( s + 2 ) + 1 )

Using these concepts the following program prints out each element of a two-dimensional array using pointer notation.

/* Pointer notation to access 2-D array elements */
main( )
{
      int  s[4][2] = {
     { 1234, 56 },
     { 1212, 33 },
     { 1434, 80 },
     { 1312, 78 }
                       } ;           
      int  i, j ;

      for ( i = 0 ; i <= 3 ; i++ )
 {
            printf ( "\n" ) ;
            for ( j = 0 ; j <= 1 ; j++ )
                  printf ( "%d ", *( *( s + i ) + j ) ) ; 
 }
}

And here is the output...

1234  56
1212  33
1434  80 
1312  78 

No comments:

Post a Comment