如何使用inteface块将函数传递给子例程? [英] How to use inteface blocks to pass a function to a subroutine?
问题描述
MainProgran
使用....
隐含无
类型装饰等
接口
函数test(x,y )
实数,INTENT(IN):: x,y
REAL :: test
END函数
结束接口
调用子程序(limit1,limit2 ,test,Ans)
结束MainProgram
这是这样做的正确方法?我很困难!同样在子例程
中,有什么我需要让它知道一个函数正在进入?在这种情况下,子例程
将是一个库,所以我不想不得不重新编译它来改变函数。
我现在知道的最优雅的方式是将你的函数放入一个模块中,这样你就不必做构建接口,但只需使用'外部'。这是一个例子。
它包含使用子程序或函数作为子程序或函数的参数的不同情况。
注意,如果你想传递数组作为参数而不接收null arraies,这里是一个提示。
模块部分:
module func_arg_test
!我用ifort编译,但其他编译器也应该没问题。
!由Kee
!撰写2017年2月20日
包含
!------------------- ------
真实函数func_func(f,arg)
!=========================== =============
!这显示了如何将参数传递给
!=================== =====================
implicit none
real,external :: f!使用external来表示f是函数的名称
real :: arg
func_func = f(arg)
结束函数func_func
实函数func_sub(subr,arg)
! ========================================
!这显示了如何通过子程序作为参数运行
!========================================
implicit none
external :: subr!使用external来指示subr是一个子例程
real :: arg
调用子(arg)
func_sub = arg
结束函数func_sub
子程序sub_func(f,arg)
!================== ======================
!这显示了如何在子程序
!中传递函数作为参数
!=== ================== ===================
real :: arg
real,external :: f
arg = f(arg)
结束子程序sub_func
子程序sub_sub(subr,arg)
!========================== ==============
!这显示了如何在子程序
中传递子程序作为参数
!=========== =============================
real :: arg
external :: subr
call subr(arg)
end subroutine sub_sub
实函数funcmat(f,mat)
!====== ==================================
!这显示了如何传递矩阵作为参数
!========================================
implicit none
real,external :: f
real,dimension(:) :: mat!当mat为
!时,mat已经被分配了,所以不需要特定的大小
integer :: sizeinfo
sizeinfo = size(mat)
funcmat = f(mat,sizeinfo)
结束函数funcmat
!----------- ---------------
实函数f1(arg)
!这个测试函数加倍数字arg
implicit no ne
real :: arg
f1 = arg * 2
返回
结束函数f1
实函数f2(arg)
!测试函数平方数arg
隐式无
real :: arg
f2 = arg * arg
返回
结束函数f2
real函数fmat(mat,sizeinfo)
!这个测试函数总结了mat
中的所有元素implicit none
integer :: sizeinfo!这是我想出的方法来解决
!限制。
real,dimension(sizeinfo):: mat!这个垫子不能确定,否则
!将不能正确接收。我不知道为什么。
fmat = sum(mat)
结束函数fmat
子程序sub(arg)
real :: arg
arg = arg * 3
结束子程序sub
结束模块
主程序:
程序主体
使用func_arg_test
隐式无
真正:: a = 5d0
真实::输出
real,dimension(:),allocatable :: mat
写入(*,*)'a ='的值,a
输出= func_func(f1,a)
* write(*,*)'a doubled'
write(*,*)output
output = func_func(f2,a)
write(*,*)'a is squared'
写(*,*)输出
输出= func_sub(sub,a)
写(*,*)'a被三倍并覆盖'
write(*,*)输出
调用sub_func(f2,a)
write(*,*)'a被平方并覆盖'
write(*,*)a
调用sub_sub(sub,a )
write(*,*)'a被三倍并被覆盖'
write(*,*)a
allocate(mat(3))
mat = (/ 1d0,10d0,1d0 /)!可分配的arrray必须在
!传递为arg之前具有确定的形状uemnt
write(*,*)'1D matrix:',mat
write(*,*)'矩阵求和:'
output = funcmat(fmat,mat)! (*,*)输出
结束程序
结果是:
a = 5.000000
a的值加倍
10.00000
a平方
25.00000
a翻三倍并被覆盖
15.00000
a被平方并被覆盖
225.0000
a翻三倍并被覆盖
675.0000
1D矩阵:1.000000 10.00000 1.000000
矩阵求和:
12.00000
I understand the interface command can be used to pass a a function into a subroutine. So for example in the main program I'd define some function and then pass it to some subroutine like:
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
Is this the correct way of doing this? I'm quite stuck! Also within the Subroutine
is there anything I need to put to let it know that a function is coming in? The Subroutine
in this case will be a library so I don't want to have to keep recompiling it to change the function.
The most elegant way I know of right now is to put your functions into a module so that you don't have to do construct interface but simply use 'external'. Here is a example to do that.
It covers different situations using subroutine or function as arguments for subroutine or function.
Notice if you want to pass array as argument without receiving null arraies, here is a tip to do that.
Module part:
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
Main program:
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
And the result is:
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
这篇关于如何使用inteface块将函数传递给子例程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!