Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site ecsvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!decvax!mcnc!ecsvax!dgary From: dgary@ecsvax.UUCP (D Gary Grady) Newsgroups: net.lang.c Subject: multidimensional arrays in C Message-ID: <458@ecsvax.UUCP> Date: Sat, 5-Jan-85 01:22:07 EST Article-I.D.: ecsvax.458 Posted: Sat Jan 5 01:22:07 1985 Date-Received: Sun, 6-Jan-85 01:15:23 EST Organization: Duke U Comp Ctr Lines: 78 <> 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