Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site rtp47.UUCP Path: utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!mcnc!rti-sel!rtp47!throopw From: throopw@rtp47.UUCP (Wayne Throop) Newsgroups: net.lang.f77 Subject: Re: arrays, anyone? Message-ID: <168@rtp47.UUCP> Date: Mon, 2-Sep-85 15:56:09 EDT Article-I.D.: rtp47.168 Posted: Mon Sep 2 15:56:09 1985 Date-Received: Thu, 5-Sep-85 06:42:23 EDT References: <390@ur-helheim.UUCP> Organization: Data General, RTP, NC Lines: 116 > Given a dimensioned fortran array A(50,300), I will set element > A(10,100)=666, just so a unique value is present. Now I pass the array > to a c program via the argument list. Given the column/row major > differences, I can address the fortran element A(10,100) as > *(apntr+9*300+99) and get the correct answer. The hassle with this is > that the dimensionality of the array must be known to the c program, ie. > 300 must be known. So far so good. > Now, in C 2-d arrays are simply an array of pointers to a linear array. Slight misconception here. In C, multi-dimensional arrays are *not* arrays of pointers to linear arrays. See the declarations below: int a[2][3]; /* multi-dimensional array */ int (*a[2]); /* array of pointers to arrays of indefinite size */ int (*a)[3]; /* pointer to array of indefinite size of arrays of 3 ints */ FORTRAN can express only the first notion (since FORTRAN lacks pointers). The diference between C multi-dimensional arrays and FORTRAN multi-dimensional arrays is that C arrays are stored in what is often called "odometer order", while FORTRAN arrays are stored in "anti-odometer order". That is, the elements of the above declared multi-dimensional array are stored in this order: a[0][0], a[0][1], a[1][2], a[1][0], a[1][1], a[1][2] while the fortran array declared INTEGER A(2,3) is stored in this order: A(1,1), A(2,1), A(1,2), A(2,2), A(1,3), A(2,3) By the way, *(a+9*300+99) or a[9*300+99] to get at A(10,100) should *NOT* have worked, since it assumes FORTRAN stores arrays in "odometer" order. (It also assumes that FORTRAN passes an array by placing the address of the array on the stack in a C-compatible form, but his is often the case, and is thus a "safe" assumption.) Anyway, what is needed is a[9+50*99]. > My question is can I access the fortran array above as a double > indirection + offset, as I would a C array? Is there any way of > accessing the array that does not need to know the dimensions to get the > offset? [Suggestions like 'do it in fortran' are not needed--thanks!!] As indicated above, the C declaration "int a[3][2];" is "equivalent to" the fortran "INTEGER A(2,3)", (where all appropriate indices are swapped on references). Thus, you should be able to do something like this: FORTRAN main program: INTEGER A(2,3) CALL INIT(A) DO 100 I=1,2 DO 90 J=1,3 PRINT *, A(I,J) 90 CONTINUE 100 CONTINUE STOP END C subroutine to initialize the array: void INIT(a) int a[3][2]; { int i,j,k=0; for(i=0;i<2;i+=1){ for(j=0;j<3;j+=1){ a[j][i] = ++k; } } } And get the output I did, namely: 1 2 3 4 5 6 Now then, as to *implicitly* passing the "shape" of the array from FORTRAN to C, there is no real way to do that. The closest (even somewhat portable) way I can see to do that is like so: INTEGER A(2,3) CALL CSUBR(A,2) ... void CSUBR(a,n) int a[], *n; { ... a[i+(*n)*j] ...; /* access FORTRAN array element A(i+1,j+1) */ } Which corresponds closely to the usual FORTRAN idiom of INTEGER A(2,3) CALL FSUBR(A,2,3) ... SUBROUTINE FSUBR( A, N, M ) INTEGER A(N,M) ... A(I,J) ... ! access FORTRAN array element A(I,J) So... why don't you do it in FORTRAN? :-) > Dave Carlson > {allegra,seismo,decvax}!rochester!ur-valhalla!dave -- Wayne Throop at Data General, RTP, NC !mcnc!rti-sel!rtp47!throopw