Fortran 返回数组策略比较

Fortran 返回数组策略比较,fortran,fortran90,Fortran,Fortran90,在Fortran中,我可以使用三种方法从子例程返回数组。第一个是通过intent(out)参数。第二个是通过一个函数,该函数的数组为result。第三种方法是让函数具有一个指向数组的指针,该指针在函数中分配 每种方法的优缺点是什么?我的做法是在函数只改变一个变量而不产生其他输出时使用函数返回。如果更改了多个变量或过程执行了其他操作,我会将输出变量放在参数列表中。这是一种风格选择。使用指针可能会造成内存泄漏,特别是使用作为函数参数返回的指针,因此我将避免使用此选项,除非在特定情况下有令人信服的原因

在Fortran中,我可以使用三种方法从子例程返回数组。第一个是通过
intent(out)
参数。第二个是通过一个函数,该函数的数组为
result
。第三种方法是让函数具有一个指向数组的指针,该指针在函数中分配


每种方法的优缺点是什么?

我的做法是在函数只改变一个变量而不产生其他输出时使用函数返回。如果更改了多个变量或过程执行了其他操作,我会将输出变量放在参数列表中。这是一种风格选择。使用指针可能会造成内存泄漏,特别是使用作为函数参数返回的指针,因此我将避免使用此选项,除非在特定情况下有令人信服的原因

更新:intent(out)数组参数没有问题。。。无需假设阵列的大小,如下例所示:

module example_one

implicit none

contains

subroutine two_arrays ( in_arr, out_arr )

   integer, dimension (:), intent (in) :: in_arr
   integer, dimension (:), allocatable, intent (out) :: out_arr

   integer :: i, len

   len = size (in_arr)

   allocate ( out_arr (1:len) )

   do i=1, len
      out_arr (i) = 3 * in_arr (i)
   end do

return

end subroutine two_arrays

end module example_one


program test

use example_one

implicit none

integer, dimension (1:5)  :: in_arr = [ 1, 2, 4, 5, 10 ]
integer, dimension (:), allocatable :: out_arr

write (*, *) allocated ( out_arr)
call two_arrays ( in_arr, out_arr )

write (*, *) size (out_arr)
write (*, *) out_arr

write (*, *) allocated ( out_arr)
deallocate ( out_arr )
write (*, *) allocated ( out_arr)

stop

end program test
  • `intent(out)`可能是个问题,因为您必须假设传入的数组的大小
  • 返回数组也是一个问题,因为接收代码必须对返回的数组的大小进行假设
  • 指向数组的指针存在与大小有关的问题,另外还有假设指针是否关联的问题
  • 另一种方法是创建一个模块,在该模块中有一个类型,该类型包含一个可分配数组和一个详细说明数组大小的整数:
  • 那么您的功能可以是:

    function myvecreturner(someparam)
        use mymodule
        type(myvector)::myvecreturner
        integer::someparam
    
        allocate(myvecreturner%values(someparam))
        myvecreturner%length = someparam
    end function
    

    您可以愉快地传递这些myvector类型。只需记住在使用完阵列后释放它们…

    使用不同的策略返回时是否存在诸如堆栈崩溃之类的问题?假设返回一个100万real的数组。您是否会使堆栈溢出,并将其从函数上下文复制到调用方上下文?从技术上讲,您已经具有数组的大小,而不需要类型。使用
    size
    进行查询也可以达到同样的效果。对于#2也有解决方案。函数可以返回可分配数组。看见
    function myvecreturner(someparam)
        use mymodule
        type(myvector)::myvecreturner
        integer::someparam
    
        allocate(myvecreturner%values(someparam))
        myvecreturner%length = someparam
    end function