# Fortran, passing an array to multiple subroutines

• Fortran
Hi guys,

I am kind of a newbie to fortran and I'd like to ask a simple question.

In the code below, I have a main program with one subroutine. It's a simple one.
In the main code I am filling an array with elements from 1 to 10. Then I am passing this array to a subroutine "sub", where I am computing the logarithms of the array elements. However, I don't want to return the array back in to the main program. In fact, I want the the logarithms to be calculated in the subroutine only.
However, when I print the array elements just after the call to the subroutine, I notice that the array elements are actually the logarithms of the latter. When I print the elements before to the call of the subroutine, the elements print fine i.e 1,2,3,4...etc. How do say fortran not to alter the array elements in the main program. I am asking this because later, I need to pass the original array elements to a second subroutine. That is, if a call a second subroutine e.g "sub2" with the same arguments as the first one, I notice that the main program actually passes the logarithms i.e the elements which have been calculated in the first subroutine.

I hope my question is clear enough.

BTW: I prefer to use fortran 77. So, if you can help me by providing a fortran 77 solution, I'd appreciate that!

c***********************************************************************
implicit none

integer i,n
parameter(n=10)
real arr(n)
c***********************************************************************

do i = 1, 10
arr(i) = real(i)
end do

print*,arr ! here it prints: 1,2,3,4 ....etc which is what I want

call sub(n,arr)

print*,arr ! here it prints the logarithm of the values, which is not what I want. I'd like the origininal array because I am going to pass it to another subroutine.

end
c***********************************************************************
subroutine sub(n,ar)

integer i,n
real :: ar(n)

do i = 1, 10
ar(i) = alog10(ar(i))
end do

end

Related Programming and Computer Science News on Phys.org
Ackbach
Gold Member
You need to pass by value, not by reference. You could try this:

call sub(n,%VAL(arr))

The %VAL function is not standard in FORTRAN77, though. I take that to mean you might have access to it, or you might not. See this reference.

You need to pass by value, not by reference. You could try this:

call sub(n,%VAL(arr))

The %VAL function is not standard in FORTRAN77, though. I take that to mean you might have access to it, or you might not. See this reference.
Hi Ackbeet,

If I wanted to pass all the elements by values then I'd use : call sub(n, arr(1:10))

But either way, it prints the logarithms after the "call" statement rather than the original array.

Ackbach
Gold Member
Well, another option would be to define a new array in the subroutine, and not overwrite the existing array. So your subroutine looks like this:

Code:
subroutine sub(n,ar)

integer i,n
real :: newar(n)

do i = 1, 10
newar(i) = alog10(ar(i))
end do

end
It's been awhile since I've done FORTRAN, so I'm not entirely sure what the "real :: ar(n)" line is doing in your original code. In any case, rest assured that if the argument 'ar' to the subroutine never appears on the LHS of an assignment operator, then it will remain in memory untouched.

Well, another option would be to define a new array in the subroutine, and not overwrite the existing array. So your subroutine looks like this:

Code:
subroutine sub(n,ar)

integer i,n
real :: newar(n)

do i = 1, 10
newar(i) = alog10(ar(i))
end do

end
It's been awhile since I've done FORTRAN, so I'm not entirely sure what the "real :: ar(n)" line is doing in your original code. In any case, rest assured that if the argument 'ar' to the subroutine never appears on the LHS of an assignment operator, then it will remain in memory untouched.
Thanks Ackbeet! Defining a new array solved the problem. You're right, in that way I am not overwriting the old array.