If I have two arrays, say A and B, and let's say my declarations are:
real(kind=8) :: A(1, 10)
real(kind=8), intent(in) :: B(1, 20)
where B is an array that I am receiving from somewhere. I have a function F, which needs the data I have stored in B, but B has stored data in packs of 10 (that is, elements 1 to 10 belong to a particular set, 11 to 20 to a different set and so on), so I am using A to store 10 values of B sequentially.
If I call a function by passing A, I am technically passing the address of the first element of the array A right? So if I run a loop:
do i = 1, 2
A(1, 1) = B(1, 10*i - 9)
call F(A)
end do
am I actually asking the function F to read from the element (10*i - 9) in the ith loop? (like 1st element in the first loop, 11th element in the second loop) Of course, this is equivalent to writing
do i = 1, 2
call F(B(1, 10*i - 9))
end do
but I wanted to make it absolutely sure that I understand about passing of array pointers via functions and subroutines properly. Please do let me know if there are some blatant errors in whatever I have said here. Thanks
When the dummy argument of F
is declared like
real(kind=8), intent(in) :: B(1, 10)
we open ourselves up to something called sequence association.1
In this case the subroutine reference
call F(B(1, 10*i - 9))
does work on that given element of B
and the following nine elements. In that sense, you are "passing the address of the element". Strictly, though, you are passing a sequence of ten elements to the subroutine, not an address. (The compiler will likely implement this as a pass-by-reference, but there is a difference.2)
In the subroutine reference
call F(A)
you are referencing the whole array A
. There is still a ten element sequence, this time built from the first element of A
. Again, this is almost like passing the address of that first element.
Where you are going wrong, however, is in thinking that
A(1, 1) = B(1, 10*i - 9)
is working towards what you want. It isn't.
This assignment is copying one element from B
to the first element of A
. That's really a copy. It's a brand new value at a brand new address. There's no implied copy of any other element of B
to any other element of A
.
You could use a pointer array A
with pointer assignment to a section of B
, but that's different and in this case quite unnecessary (so I won't by default show). Or a full array section copy of B
to the whole array A
, but again that's different.
Finally, don't forget F(B(1,10*i-9:10*i))
.
1 See other questions and answers here; also applies to assumed-size arrays like real B(1,*)
.
2 You'll see this difference if you have a compiler happy to check that lengths of the element sequences match. As a naive passing of an address, you can supply a shorter sequence than required and then run over that in the subroutine; as a true sequence, a compiler can warn you that it's too short.