Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran, passing an array to multiple subroutines

  1. Jul 9, 2013 #1
    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
     
  2. jcsd
  3. Jul 9, 2013 #2

    Ackbach

    User Avatar
    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.
     
  4. Jul 9, 2013 #3
    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.
     
  5. Jul 9, 2013 #4

    Ackbach

    User Avatar
    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 (Text):
    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.
     
  6. Jul 9, 2013 #5
    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
     
  7. Jul 9, 2013 #6

    Ackbach

    User Avatar
    Gold Member

    You're very welcome!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook