2014-10-13 2 views
4

У меня есть функция, которая возвращает массив, скажемКак объявить тип функции, которая возвращает массив в Fortran?

function f(A) 
    implicit none 
    real, intent(in) :: A(5) 
    real, intent(out) :: f(5) 

    f = A+1 
end 

Мой вопрос, как я могу определить f в основном блоке программы? Например.

program main 
    implicit none 
    real :: A(5) 
    real, dimension(5), external :: f ! does not work 

    ... 
end 
+0

Для функции, возвращающей массив, то требуется _explicit interface_. См. Например, http://stackoverflow.com/q/24910843/3157076. – francescalus

ответ

6

Вам нужен явный интерфейс. Вы можете сделать это несколькими способами.

  1. Явное в обзорном блок, который вызывает f:

    interface 
        function f(A) 
        implicit none 
        real, intent(in) :: A(5) 
        real :: f(5) 
        end function 
    end interface 
    
  2. Place функция в Вашей области программы хоста в качестве внутренней функции:

    program main 
        ... 
    contains 
        function f(A) 
        implicit none 
        real, intent(in) :: A(5) 
        real :: f(5) 
    
        f = A+1 
        end 
    end program 
    
  3. Поместите функцию в модуль:

    module A 
    contains 
        function f(A) 
        implicit none 
        real, intent(in) :: A(5) 
        real :: f(5) 
    
        f = A+1 
        end 
    end module 
    
    program main 
        use A 
        ... 
    end program 
    
  4. Используйте явный интерфейс из другой процедуры с теми же аргументами и возвращаемым типом, видом и рангом.

    program main 
        interface 
        function r5i_r5o(r5) 
         implicit none 
         real, intent(in) :: r5(5) 
         real :: r5i_r5o(5) 
        end function 
        end interface 
    
        procedure(r5i_r5o) :: f 
        ... 
    end program 
    
    function f(A) 
        implicit none 
        real, intent(in) :: A(5) 
        real :: f(5) 
    
        f = A+1 
    end 
    

Чистейший способ сделать это вариант # 3 с использованием модулей. Это дает вам преимущество автоматического явного интерфейса (не нужно делать опцию №1 везде, где вы звоните f) и делает вашу функцию доступной везде, где модуль используется, а не ограничен конкретным областью охвата, как в варианте № 2. Вариант №4 может быть полезен, если у вас есть много процедур с одинаковыми аргументами и типами возврата, поскольку один явный интерфейс может быть повторно использован для всех из них.

1

Это показывает три различных способа указания результатов функций, и как использовать модули для организации функции:

module so_func 

    INTEGER, PARAMETER :: MAX_SIZE = 5 

    TYPE MY_DATA 
     INTEGER :: SIZE 
     REAL, DIMENSION(MAX_SIZE) :: DATA 
    ENDTYPE 


contains 

    FUNCTION f1(A,N) RESULT(X) 
    implicit none 
    INTEGER, INTENT(IN) :: N 
    REAL, INTENT(IN) :: A(N) 
    REAL :: X(N) 
    ! .... 
    X = 1.0+A 
    END FUNCTION f1 

    TYPE(MY_DATA) FUNCTION f2(A,N) 
    implicit none 
    INTEGER, INTENT(IN) :: N 
    REAL, INTENT(IN) :: A(N) 
    ! .... 
    f2%SIZE = N 
    f2%DATA(1:N) = 1.0+A 
    END FUNCTION f2 

    FUNCTION f3(A,N) 
    implicit none 
    INTEGER, INTENT(IN) :: N 
    REAL, INTENT(IN) :: A(N) 
    REAL :: f3(N) 
    ! .... 
    f3 = 1.0+A 
    END FUNCTION f3 

end module 


program SO_RESULT 
    use so_func 
    implicit none 
    integer, parameter :: n=5 
    REAL :: A(n), y1(n), y3(n)  
    TYPE(MY_DATA) :: y2 
    INTEGER :: i 
    ! Variables 

    A =(/ (i, i=1,n) /) 

    y1 = f1(A,n) 
    y2 = f2(A,n) 
    y3 = f3(A,n) 


end program SO_RESULT 
Смежные вопросы