我理解interface命令可用于将函数传递给子例程。因此,例如在主程序中,我定义了一些函数,然后将其传递给某些子例程,如:
MainProgran
Use ....
Implicit None
Type decorations etc
Interface
Function test(x,y)
REAL, INTENT(IN) :: x, y
REAL :: test
END function
End Interface
Call Subroutine( limit1, limit2, test, Ans)
End MainProgram
这是正确的做法吗?我卡住了!同样在Subroutine
内还有什么我需要知道函数进来吗?在这种情况下,Subroutine
将是一个库,因此我不想继续重新编译它以更改功能。
答案 0 :(得分:0)
简单这样做的方法就是上学,只需将函数留在外部:
program main
real f,z
external f
call subr(f,z)
write(*,*)z
end
real function f(x)
real x
f=x**2
end
!下面可能在预编译库中:
subroutine subr(f,y)
real f,y
y=f(2.)
end
out:4
当然,使用此方法,您无法使用需要显式界面的高级语言功能。 **
另一方面,如果你正在与需要函数参数的标准库接口,那么我认为这是唯一的方法。
**根据MSB的评论,您可以在子程序中使用接口块处理该问题, 例如,如果我们想传递一个返回数组的函数:
function f(x)
real x,f(2)
f(1)=x
f(2)=x**2
end
与第一个例子中一样,f是外部函数,sub可以是 预编译库:
subroutine subr(g,y)
interface
function g(x)
real x,g(2)
end function
end interface
real y,z(2)
z=g(2.)
y=z(1)+z(2)
end
out:6
如上所述,如果依赖于需要界面的语言功能,这是非常必要的。
答案 1 :(得分:0)
模块:
module fmod
interface
function f_interf(x,y)
real, intent(in) :: x, y
real :: f_interf
end function
end interface
contains
function f_sum(x,y)
real, intent(in) :: x, y
real f_sum
f_sum = x + y
end function
function f_subst(x,y)
real, intent(in) :: x, y
real f_subst
f_subst = x - y
end function
subroutine subr(limit1, limit2, func, ans)
real limit1, limit2
procedure(f_interf) func
real ans
ans = func(limit1, limit2)
end subroutine
end module
主程序:
program pass_func
use fmod
Implicit None
real ans, limit1, limit2
limit1 = 1.0
limit2 = 2.0
call subr( limit1, limit2, f_subst, ans)
write(*,*) ans
call subr( limit1, limit2, f_sum, ans)
write(*,*) ans
end program pass_func
并输出:
-1.000000
3.000000
答案 2 :(得分:0)
我现在知道的最优雅的方法是将您的功能放入一个模块中,这样您就不必构建界面,只需使用“外部”即可。这是一个例子。
请注意,如果你想将数组作为参数传递而不接收空的arraies,这里有一个提示。
模块部分:
module func_arg_test
!I used ifort to compile but other compilers should also be fine.
!Written by Kee
!Feb 20, 2017
contains
!-------------------------
real function func_func(f, arg)
!========================================
!This shows how to pass number as argument
!========================================
implicit none
real, external::f !Use external to indicate the f is a name of a function
real::arg
func_func=f(arg)
end function func_func
real function func_sub(subr, arg)
!========================================
!This shows how to pass subroutine as arg to function
!========================================
implicit none
external::subr !Use external to indicate subr is a subroutine
real::arg
call sub(arg)
func_sub = arg
end function func_sub
subroutine sub_func(f,arg)
!========================================
!This shows how to pass function as argument
!in subroutine
!========================================
real::arg
real,external::f
arg = f(arg)
end subroutine sub_func
subroutine sub_sub(subr,arg)
!========================================
!This shows how to pass subroutine as argument
!in subroutine
!========================================
real::arg
external::subr
call subr(arg)
end subroutine sub_sub
real function funcmat(f, mat)
!========================================
!This shows how to pass matrix as argument
!========================================
implicit none
real, external::f
real,dimension(:)::mat!Here memory for mat is already allocated when mat is
!passed in, so don't need specific size
integer::sizeinfo
sizeinfo = size(mat)
funcmat = f(mat,sizeinfo)
end function funcmat
!--------------------------
real function f1(arg)
!This test function double the number arg
implicit none
real::arg
f1 = arg*2
return
end function f1
real function f2(arg)
!This test function square the number arg
implicit none
real::arg
f2 = arg*arg
return
end function f2
real function fmat(mat,sizeinfo)
!This test function sum up all elements in the mat
implicit none
integer::sizeinfo!This is the method I come up with to get around the
!restriction.
real,dimension(sizeinfo)::mat!This mat cannot be undetermined, otherwise it
!won't recevie mat correctly. I don't know why yet.
fmat = sum(mat)
end function fmat
subroutine sub(arg)
real::arg
arg = arg*3
end subroutine sub
end module
主程序:
program main
use func_arg_test
implicit none
real::a = 5d0
real::output
real, dimension(:),allocatable::mat
write(*,*) 'value of a=',a
output = func_func(f1,a)
write(*,*) 'a is doubled'
write(*,*) output
output = func_func(f2,a)
write(*,*) 'a is squared'
write(*,*) output
output = func_sub(sub,a)
write(*,*) 'a is tripled and overwritten'
write(*,*) output
call sub_func(f2,a)
write(*,*) 'a is squared and overwritten'
write(*,*) a
call sub_sub(sub,a)
write(*,*) 'a is tripled and overwritten'
write(*,*) a
allocate(mat(3))
mat = (/1d0,10d0,1d0/)!The allocatable arrray has to have a determined shape before
!pass as arguemnt
write(*,*) '1D matrix:',mat
write(*,*) 'Summation of the matrix:'
output = funcmat(fmat,mat)!elements of mat are summed
write(*,*) output
end program
结果是:
value of a= 5.000000
a is doubled
10.00000
a is squared
25.00000
a is tripled and overwritten
15.00000
a is squared and overwritten
225.0000
a is tripled and overwritten
675.0000
1D matrix: 1.000000 10.00000 1.000000
Summation of the matrix:
12.00000