From: ted.jensen@spacebbs.com (Ted Jensen) 
Newsgroups: comp.lang.c
Subject: 2-D Arrays, Revisited.
Date: 19 Nov 92 06:13:00 GMT
Distribution: world
Organization: SPACE BBS - Menlo Park, CA - 10 Lines + 4gB - 415-323-4193
Reply-To: ted.jensen@spacebbs.com (Ted Jensen) 


In Message-ID: <17489#pitt.UUCP> fahad@cs.pitt.edu (Fahad A Hoymany)
writes:

> I am writing a function that should accept a 2-D array (hopefully
> of any size), operate on that array, and returns 'anything' to
> the caller. Please don't suggest I use double pointers because I
> do not want to restrict the users of my function to use them when
> they are used to declaring arrays as : int a[2][5].


int your_function(int a[][5]);

I know you are not going to like this, but you are going to have
to include the value of the second dimension, though this might
be done with a define as in:

#define ROWS 2
#define COLS 5

int a[ROWS][COLS];

int your_function(int a[][COLS]);       /* function prototype */

The reason is simple enough.  When you have a two dimensional
array as a parameter the compiler treats it as a pointer and
within your_function when you write:

    a[1][3] = 17;

the compile must compile this as if it were written:

    *(a + COLS*1 +3) = 17;

which it cannot do without knowing the value of the second
dimension, COLS.  Thus were you to write the function in a
seperate file, one which did not contain the definition of a as
int a[ROWS][COLS], the compiler would not know what to do.

If you want a function which will handle any 2 dimensional array
you might try passing an integer pointer and an integer such as
in the following code:

------------------------------------------------------
#include <stdio.h>

void my_func(int *a, int ncols);

int arrayA[5][12];
int arrayB[7][21];

void main(void)
{
  printf("\n arrayA initial value = %d\n",arrayA[2][3]);
  my_func(arrayA,12);
  printf("arrayA modified value = %d\n",arrayA[2][3]);
  printf("arrayB initial value = %d\n",arrayB[2][3]);
  my_func(arrayB,21);
  printf("arrayB modified value = %d\n",arrayB[2][3]);
}


void my_func(int *a, int ncols)
{
  *(a + ncols*2 + 3) = 17;
}
-----------------------------------------
Note that you must use the pointer notation instead of array
notation within your function.  Since there is no need for your
user to see the internals of your function this should not be
a problem.  You could also pass the function the number of rows
as well as the number of cols which might prove useful depending
on what the function is doing.

The above gives a Suspicious pointer conversion warning on the
two calls to my_func() in main() simply because arrayA and arrayB
are _not_ simple integer pointers.  The warning can be avoided by
using    my_func((int *)arrayA,12);   as the call instead of what
is shown.  Either the cast or the warning may bother you user so
you should be aware of that.

This is my first thought on this problem, so it may not be the
most elegant solution.  If others do better I would appreciate
the opprtunity to look at their approaches.

Hope this helps!  Ted Jensen  Redwood City, Calif.


 * SLMR 2.1a * 
                                                            
Newsgroups: comp.lang.c