Thursday, November 20, 2008

Variably Dimensioned Arrays in c programming

Variably Dimensioned Arrays

While dealing with Scientific or Engineering problems one is often required to make use of multi-dimensioned array. However, when it comes to passing multidimensional arrays to a function C is found wanting. This is because the C compiler wants to know the size of all but the first dimension of any array passed to a function. For instance, we can define a function compute ( int n, float x[] ), but not compute ( int n, x[][]).
Thus, C can deal with variably dimensioned 1-D arrays, but when an array has more than one dimension, the C compiler has to know the size of the last dimensions expressed as a constant. This problem has long been recognized, and some of the solutions that are often used are:
Declare the arrays in the functions to be big enough to tackle all possible situations. This can lead to a wastage of lot of precious memory in most cases. Another solution is to construct multiple-dimension array as an array of pointers. For example, a matrix (2-D array) of floats can be declared as a 1-D array of float pointers, with each element pointing to an array of floats. The problem with this method is that the calling function has to define all arrays in this fashion. This means that any other computations done on the arrays must take this special structure into account.
Another easy solution, though seldom used, exists. This is based on the following method:
Pass the array to the function as though it is a pointer to an array of floats (or the appropriate data type), no matter how many dimensions the array actually has, along with the dimensions of the array. Reference individual array elements as offsets from this pointer.Write your algorithm so that array elements are accessed in storage order. The following program for multiplying two matrices illustrates this
procedure.

# define M 3
# define N 2
# define P 4
float a[M][N], b[N][P], c[M][P] ;
void mulmat ( int, int, int, float*, float*, float* ) ;
main( )
{
int i, j ;
for ( i = 0 ; i <>
for ( j = 0 ; j <>
a[i][j] = i + j ;

for ( i = 0 ; i <>
for ( j = 0 ; j <>
b[i][j] = i + j ;
mulmat ( M, N, P, a, b, c ) ;
for ( i = 0 ; i <>
{
printf ( "\n" ) ;
for ( j = 0 ; j <>
printf ( "%f\t", c[i][j] ) ;
}
}
void mulmat ( int m, int n, int p, float *a, float *b, float *c )
{
float *ptrtob, *ptrtoc ;
int i, j, k, nc ;

/* set all elements of matrix c to 0 */
for ( i = 0 ; i <>
*( c + i ) = 0 ;
for ( i = 0 ; i <>
{
ptrtob = b ;
for ( k = 0 ; k <>
{
ptrtoc = c ;
for ( j = 0 ; j <>
*ptrtoc++ += *a * *ptrtob++ ;
a++ ;
}
c += p ;
}
}
We know that C stores array elements in a row-major order. Hence to ensure that the elements are accessed in the storage order the above program uses a variation of the normal matrix-multiplication procedure. The pseudo code for this is given below:

for i = 1 to m
for j = 1 to p
c[i][j] = 0
end
for k = 1 to n
for j = 1 to p
c[i][j] = c[i][j] + a[i][k] * b[k][j]
end
end
end

No comments:

Blog List