定义返回数组的函数

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:主要问题是你需要函数在模块中(或在程序中contained),以便有一个自动显式接口: (编辑添加:或者像 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 中进行了非常互动的讨论。我不知道resultelemental。不过,我更倾向于@Jonathan,因为它不需要辅助功能func

以上是关于定义返回数组的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何从用户定义的函数返回 3D 数组?

返回自定义类数组的c ++函数会出错

C++指针问题,请问如何定义一个返回值为结构体指针数组的函数?

定义返回数组的函数

C语言中,return语句怎么样返回一个数组?

c语言如何返回一个数组?