Re: [C] functions and 2D arrays?

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 01/09/04


Date: Thu, 8 Jan 2004 19:16:21 -0500 (EST)


On Thu, 8 Jan 2004, Leor Zolman wrote:
>
> On Thu, 08 Jan 2004 22:07:03 GMT, Elliot Marks wrote:
> >
> >This works, and I like the idea of using typedef, but to solidify
> >my understanding, can you show me how to do it without typedef? I
> >tried substituting <int(*a2dptr)[3][3]> in the prototype and
> >declaration but it wouldn't compile.

  You might try again. If you substitute it really right, it'll
work.

  typedef int (*foo)[3][3];

tells the compiler -- or you yourself -- to substitute
'int (*bar)[3][3]' for every instance of 'foo bar' in the code.
Roughly speaking, of course. So you would translate

  foo myfunc();
to
  int (*myfunc)()[3][3];
and
  foo myfunc ( foo );
to
  int (*myfunc)(int (*)[3][3])[3][3];

It's just a matter of bookkeeping with all those parentheses. If
you practice it often enough, you'll find it quite natural. The
"inside-out" way that C parses declarations is the most important
"rule" of C, IMHO (although "The Rule" is a close second).

  Also, you've got one more layer of indirection there than you
really need. There's no reason to be passing around *pointers*
to arrays of arrays of int, when you could be passing pointers
to arrays of int. E.g.,

    #include <stdio.h>

    void func(int a2dp[3][3])
    {
        int i, j;
        for (i=0; i < 3; ++i)
          for (j=0; j < 3; ++j)
            a2dp[i][j]++;
        return;
    }

    int main(void)
    {
        int data[3][3] = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}};
        func(data);
        printf("%d\n", data[0][0]);
        return 0;
    }

  The only reason I can see to pass around pointers to the array
is for type-safety; but it would be better in that case, as far as
I can tell, to go the whole hog and write handlers for a 'struct'
encapsulating the array entirely. E.g.,

    struct TwoDArray
    {
        int arr[3][3];
    };

    /* !!! Makes a real live copy of the array, unlike the old 'func' */
    struct TwoDArray *func(struct TwoDArray *a2dp)
    {
        int i, j;
        struct TwoDArray *p = malloc(sizeof *p);
        if (p == NULL)
          return NULL;
        for (i=0; i < 3; ++i)
          for (j=0; j < 3; ++j)
            p[i][j] = a2dp[i][j]+1;
        return p;
    }

  Maybe this is more like what you're looking for?

-Arthur



Relevant Pages

  • Re: why cant functions return arrays
    ... int f; ... have been able to pass and return fixed-size arrays by value by ... The code which uses foo typically requires almost ... is too burdensome for the programmer. ...
    (comp.lang.c)
  • Re: Returning structs containing arrays
    ... > of ints and an int. ... contains two pointers and an integer. ... arrays if you initialize them to point to allocated memory. ... The typedef "arrays" doesn't name a structure type; ...
    (comp.lang.c)
  • Re: survival of c++
    ... C++ function's have a type and you can typedef that type ... > int main ... typedef void func_t; ... A similar thing happens with arrays: ...
    (comp.lang.cpp)
  • Re: void func () returning value?
    ... this feature can be extremely useful. ... T foo() {... ... In at some point in the future I might decide to change the typedef to ...
    (comp.lang.c)
  • Re: passing invalid datatype
    ... foo and bar are incompatible, then that's a constraint violation, and ... But wchar_t is a typedef for some integer type, ...
    (comp.lang.c)