Fortran, passing an array to multiple subroutines

In summary, you have a problem with passing an array from one subroutine to another. You might be able to solve the problem by defining a new array, or by passing the array by value instead of by reference.
  • #1
Biederman
9
0
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 into 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
 
Technology news on Phys.org
  • #2
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.
 
  • #3
Ackbeet said:
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,

Thank you for the link!
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.
 
  • #4
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.
 
  • #5
Ackbeet said:
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.

I appreciate your help!

Regards,

Abedin
 
  • #6
You're very welcome!
 

FAQ: Fortran, passing an array to multiple subroutines

What is Fortran?

Fortran is a high-level programming language commonly used in scientific and engineering applications. It was developed in the 1950s and is known for its efficient handling of mathematical and scientific computations.

How do you pass an array to multiple subroutines in Fortran?

In Fortran, arrays can be passed to subroutines by reference, meaning that the subroutine can access and modify the original array in the main program. This is done by declaring the array as an argument in the subroutine and using the "intent(in/out/inout)" specifier to specify whether the subroutine can only read from the array, can only modify the array, or can both read from and modify the array.

What is the advantage of passing arrays to multiple subroutines in Fortran?

By passing arrays to multiple subroutines, the same array can be used and modified by different subroutines without having to create multiple copies of the array. This can save memory and improve program efficiency.

Can arrays of different dimensions be passed to multiple subroutines in Fortran?

Yes, arrays of different dimensions can be passed to multiple subroutines in Fortran. The subroutine must declare the array with the same dimensions as the array being passed to it, and the dimensions must be specified in the subroutine call.

Is it possible to pass arrays to subroutines in Fortran without using the "intent" specifier?

Yes, it is possible to pass arrays to subroutines in Fortran without using the "intent" specifier. In this case, the subroutine will not be able to modify the original array, but will have access to read from it.

Similar threads

Replies
3
Views
2K
Replies
59
Views
9K
Replies
5
Views
7K
Replies
29
Views
2K
Replies
4
Views
2K
Replies
25
Views
1K
Replies
8
Views
4K
Replies
11
Views
1K
Back
Top