Xref: utzoo comp.lang.c:7449 comp.lang.fortran:449 Path: utzoo!utgpu!water!watmath!clyde!rutgers!umd5!trantor.umd.edu!chris From: chris@trantor.umd.edu (Chris Torek) Newsgroups: comp.lang.c,comp.lang.fortran Subject: Re: Conformant Arrays in C Keywords: ANSI C Fortran Message-ID: <2336@umd5.umd.edu> Date: 22 Feb 88 08:33:24 GMT References: <42529@sun.uucp> <7297@brl-smoke.ARPA> <676@cresswell.quintus.UUCP> Sender: ris@umd5.umd.edu Reply-To: chris@trantor.umd.edu (Chris Torek) Organization: University of Maryland, College Park Lines: 82 In article <676@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >Background: > David Hough sent me his comments on dpANS C. > He wants a language which can do at least as much as Fortran could. > > One of his criteria was that you should be able to write > subroutines that handle multi-dimensional arrays sensibly. I would claim that the `best' way to do this is to use the row-vector approach. To create a two-dimensional array, e.g., do the following: typedef struct dmat2 { int m2_nrows; int m2_ncols; double **m2_m; /* row vectors */ double *m2_data; } dmat2; dmat2 * create(rows, cols) register int rows, cols; { register dmat2 *m; register int r; m = (dmat2 *)malloc(sizeof(dmat2)); if (m == NULL) return (NULL); m->m2_rows = rows; m->m2_cols = cols; m->m2_m = (double **)malloc(rows * sizeof(double *)); if (m->m2_m == NULL) { free((char *)m); return (NULL); } m->m2_data = (double *)malloc(rows * cols * sizeof(double)); if (m->m2_data == NULL) { free((char *)m->m2_m); free((char *)m->m2_data); } for (r = 0; r < rows; r++) m->m2_m[r] = &m->m2_data[r * cols]; return (m); } These arrays can then be used as m->m2_m[r][c] = val; and parts of the array can be passed to functions with f(&m->m2_m[off], rows - off, cols); Note that a whole matrix can be passed (by reference) with f(m); If you dislike having to specify the range for subarrays, you could create a `make subarray' function: dmat2 * makesub(m, roff, coff, rsize, csize) dmat2 *m; int roff, coff, rsize, csize; { if (m->m2_rows - roff < rsize || m->m2_rows - coff < csize) /* it is not that big! */... etc. } This does, of course, require more memory to describe, but row vectors are generally faster anyway. Since the whole matrix is still there as a single block of memory, you can use existing routines as well (by passing m->m2_data). So why is this solution insufficient? -- In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163 (hiding out on trantor.umd.edu until mimsy is reassembled in its new home) Domain: chris@mimsy.umd.edu Path: not easily reachable