定义返回数组的函数
Posted
技术标签:
【中文标题】定义返回数组的函数【英文标题】:Defining a function returning an array 【发布时间】:2014-09-14 15:48:27 【问题描述】:我有以下代码:
Program function_as_an_array
implicit none
integer:: i
integer, parameter:: N=10
real*8:: x(N),y(N),f(N)
do i=1,N
x(i)=float(i)
end do
call func(f,N,x)
open(unit=20, file='test.dat')
do i=1,N
y(i)=f(i)
write(20,*) x(i),y(i)
end do
close(20)
Stop
End Program function_as_an_array
Subroutine func(f,N,x)
implicit none
integer i,N
real*8:: x(N),f(N)
do i=1,N
f(i)=x(i)**2
end do
end Subroutine func
我想让程序确实适合
“函数作为一个数组”,即我想用function f
替换Subroutine func
并获得相同的结果(在主程序中,我希望保留一个类似y=f(x,N)
的语句)。我该怎么做?
【问题讨论】:
【参考方案1】:函数返回数组没有问题,就像this question and answer:主要问题是你需要函数在模块中(或在程序中contain
ed),以便有一个自动显式接口: (编辑添加:或者像 Alexander Vogt 的回答一样明确定义界面)
module functions
contains
function func(N,x)
implicit none
integer, intent(in) :: N
double precision, intent(in) :: x(N)
double precision, dimension(N) :: func
integer :: i
do i=1,N
func(i)=x(i)**2
end do
end function func
end module functions
Program function_as_an_array
use functions
implicit none
integer:: i
integer, parameter:: N=10
double precision:: x(N),y(N)
do i=1,N
x(i)=float(i)
end do
y = func(N,x)
open(unit=20, file='test.dat')
do i=1,N
write(20,*) x(i),y(i)
end do
close(20)
Stop
End Program function_as_an_array
但是请注意,这种函数 - 对数组中的每个元素应用相同的操作 - 使用 Fortran elemental
函数可以更好地完成,定义为简单地在标量上工作,Fortran 将自动将其映射到所有元素给你一个数组:
module functions
contains
elemental double precision function f(x)
implicit none
double precision, intent(in) :: x
f = x**2
end function f
end module functions
Program function_as_an_array
use functions
implicit none
integer:: i
integer, parameter:: N=10
double precision:: x(N),y(N)
do i=1,N
x(i)=float(i)
end do
y = f(x)
open(unit=20, file='test.dat')
do i=1,N
write(20,*) x(i),y(i)
end do
close(20)
Stop
End Program function_as_an_array
这样做的好处是它现在可以自动处理标量和任何等级的数组。只要有可能,最好让编译器为您完成工作。
【讨论】:
基本函数...不错 ;-)【参考方案2】:这对我有用:
Program function_as_an_array
implicit none
integer:: i
integer, parameter:: N=10
real*8 :: x(N),y(N),f(N)
interface func
function func(x,N) result(f)
implicit none
integer N
real*8:: x(N),f(N)
end function
end interface
do i=1,N
x(i)=float(i)
end do
f = func(x,N)
open(unit=20, file='test.dat')
do i=1,N
y(i)=f(i)
write(20,*) x(i),y(i)
end do
close(20)
Stop
End Program function_as_an_array
function func(x,N) result(f)
implicit none
integer i, N
real*8:: x(N),f(N)
do i=1,N
f(i)=x(i)**2
end do
end function
你需要:
将result
用于数组值返回变量[编辑] 或将func 指定为real*8:: func(N)
。有关详细信息,请参阅 cmets。
为外部函数使用显式接口(或具有隐式接口的模块,请参阅 Jonathan Dursi 的回答)
然后,可以直接将函数的返回值赋值给数组。
【讨论】:
在这种情况下你正式需要使用result
吗?我通常没有,到目前为止它对我来说一直有效——但仅仅因为 gfortran/ifort 允许它并不意味着它不是标准所要求的,而且我从来没有理由仔细研究过。
前段时间我遇到了没有定义的问题......从那以后我就养成了这样做的习惯。
嗯 - 我应该看看标准是怎么说的。我注意到也建议使用这种方法here。无论如何我喜欢结果语法,我只是从来没有完全养成使用它的习惯。
好吧,我在标准(第 12.6.2.2 章)中找不到任何强制一种或另一种形式的内容。我会改变我的答案...
@AlexanderVogt 和@JonathanDursi:感谢你们俩。并且在 cmets 中进行了非常互动的讨论。我不知道result
或elemental
。不过,我更倾向于@Jonathan,因为它不需要辅助功能func
。以上是关于定义返回数组的函数的主要内容,如果未能解决你的问题,请参考以下文章