Fortran Fortran, passing an array to multiple subroutines

Click For Summary
The discussion centers around a Fortran programming issue where a user is trying to prevent a subroutine from modifying an array passed from the main program. The user fills an array with values from 1 to 10 and calls a subroutine to compute the logarithms of these values. However, after the subroutine call, the original array is altered, showing logarithmic values instead of the intended original values. To solve this, suggestions include passing the array by value instead of by reference, although the %VAL function is not standard in Fortran 77. A more effective solution proposed is to define a new array within the subroutine to store the logarithmic values, ensuring the original array remains unchanged. This approach successfully resolves the issue, allowing the user to retain the original array for further processing in subsequent subroutines.
Biederman
Messages
9
Reaction score
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
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.
 
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.
 
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.
 
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
 
You're very welcome!
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 59 ·
2
Replies
59
Views
11K
  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 29 ·
Replies
29
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 25 ·
Replies
25
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 11 ·
Replies
11
Views
2K