How to pass arbitrary 2-d array argument ?

Rory Jacobs rory at maccs.dcss.mcmaster.ca
Mon Jan 7 02:20:17 AEST 1991


In article <1991Jan6.044056.23028 at noose.ecn.purdue.edu> luj at delta.ecn.purdue.edu (Jun Lu) writes:
>It would be nice if I can have a "subroutine" which takes arbitrary matrices as
>arguments and performs some operations on them. The dimensions of the 2-d
>array are not known a priori.  In other words, how do you add two
>matrices together portably in C ? ( see following scenario descriptions )
>
>main()
>{
>     double m1[4][2], m2[4][2], m[4][2];
>     double a[5][5], b[5][5], c[5][5];
>
>     /* init m1, m2 ... */
>
>
>     madd(m1, m2, m, 4, 2);
>     madd(a, b, c, 5, 5);
>
>     /* ... */
>
>}
>
>madd(a, b, c, m, n)
> /* args --- how ???(Note n is not known at compile time, but we assume that
>    the type of the 2-d array elements are known, i.e. double */
>{
>    /*
>     * some work --- how ????
>     */
>
>     for (i = 0; i < m; i++)		/* fucntionality of madd() */
>	for (j = 0; j < n; j++)
>	    c[i][j] = a[i][j] + b[i][j];
>
>}


Use pointer arithemetic, as in the following way:

/*-------------------*/
  void madd(a,b,c,m,n)
/*-------------------*/
double *a,*b,*c;
int m,n;
{
   for (i=0;i<m;i++) {
      for (j=0;j<n;j++) {
         *(c+j+i*n) = *(a +j+i*n) + *(b+j+i*n);
      }     
   }
}

Explaination:  memory is stored sequentially --- including
multi-dimensional arrays.  Since we know that in C they are
stored in row-major form (row-by-row) and that the name of 
a array can be considered a pointer to the array, we can deal
with the pointer.

Calculating addresses from a two-dimensional array:

  --
  | a11  a12     .....    a1n |
  | a21  a22     .....    a2n |
  | ...                       |
  | ai1  ai2  ... aij ... ain |
  | ...                       |
  | am1  am2     .....    amn |
  --                         --


We want to know the number of entries up to and including the 
aij in the array.  This is the number of entries in complete 
rows before the ith row (i-1) * n , and the number of entries 
to the aij (which is j)

   a[i][j] = *(a+(i-1)*n +j)

But now we must remember C indices start at 0, so M ranges from 0 to
m-1, and N from 0 to n-1, ie. the one is already subtracted for you.
thus
   a[i][j] = *(a+i*n+j)

For a more decent treatment of how to calculate addresses (it is
a sunday morning after saturday night) see a half-way-descent 
discrete math book.

   Sure hope this helps,
      Rory Jacobs


Rory Jacobs                                   Who me?!?
rory at maccs.dcss.mcmaster.ca                   Let's go Flyers!
...!uunet!uati!utgpu!maccs!rory               I thought it was easy...
Department of Computer Science and Systems    Boring (yawn)!
McMaster University, Hamilton, Ont            Let's have some fun.




More information about the Comp.lang.c mailing list