multidimensional arrays in C

D Gary Grady dgary at ecsvax.UUCP
Sat Jan 5 16:22:07 AEST 1985


<>
Sorry to belabor this point, but judging from the mail I'm getting, many
people are still very confused about multidimensional C arrays.  I'll
try to be brief, and I hope this substitutes for individual responses to
my mail (I have had trouble reaching several sites).

A declaration of the form

int x[3][5];

allocates 30 bytes of storage (assuming 2 bytes per integer).  These 30
bites can be considered 3 adjacent arrays of 5 integers each.  No
pointers to these 3 arrays of integers are created.  In a reference of
the form

foo = x[2][4];

(say), the offset of the appropriate element in x is computed by the
expression

x + 2*sizeof(x[0]) + 4*sizeof(x[0][0]);

where the [0] could be replaced by any subscript.  Note that
sizeof(x[0][0]) is 2: the size of an integer.  More germane is the fact
that sizeof(x[0]) is 10, or the length of a row in bytes.  The important
point is that C _must_ know about that [5] in the declaration in order
to perform this calculation.

In a subroutine, the declaration

foo(x)
int x[][];

CANNOT be used to pass an array declared as above (x[3][5], I mean).  If
your compiler accepts this parameter declaration (a few won't), it will
treat it as identical to

foo(x)		or		foo(x)
int **x;	equivalently	int *x[];

which simply cannot produce correct results for an attempt to pass good
old x.  It IS possible to create an array of pointers to arrays and use
int **x or its variants to get at the elements.  It is also possible to
access elements of a conventional two-dimensional array passed as a
parameter by treating it as a one-dimensional array and doing the
subscript calculation "by hand."  And, of course, one can specify the
dimension sizes in the subroutine (optionally omitting the first one).

The problem is that you can't write a subroutine that handles two (or
higher) dimensional arrays without knowing either coding in constant
dimensions or doing the subscript calculation by hand.  That is a very
annoying limitation to anyone trying to hawk C as an alternative to
FORTRAN (which handles variable-sized arrays quite simply).

If I have still not managed to convince the folks who mail me K&R quotes
without knowing what they mean (come on: :-)), I have a suggestion:
Let's see you do it.  Write the subroutine that will print out the
elements of this matrix, one row per line, WITHOUT using a constant
dimension and WITHOUT treating the passed array as one-dimensional.  I
don't think it can be done.  Here's a main program:

extern print_it();		/* Note your routine is external! */

main()
{
int x[2][3] = {{1, 2, 3}, {4, 5, 6}};	/* Subject to change */

print_it(x,2,3);
}

Best,

-- 

D Gary Grady
Duke University Computation Center, Durham, NC  27706
(919) 684-4146
USENET:  {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary



More information about the Comp.lang.c mailing list