返回数组策略比较

发布于 2024-10-10 03:42:30 字数 160 浏览 2 评论 0原文

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

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

In Fortran, I can return arrays from a subroutine with three approaches. The first one is via an intent(out) parameter. The second one is via a function having the array as result. The third one is to have a function having as result a pointer to array, which is allocated in the function.

What are the advantages and disadvantages of each approach ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-10-17 03:42:30

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

更新:意图(输出)数组参数没有问题...不需要对数组的大小进行假设,如以下示例所示:

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

My practice is to use a function return when the function alters only one variable and makes no other output. If multiple variables are changed or the procedure performs other actions I would place the output variables in the argument list. This is a style choice. It is possible to create memory leaks with pointers, especially with pointers returned as function arguments, so I would avoid this option unless there was a compelling reason in the particular case.

UPDATE: There is no problem with an intent (out) array argument ... no assumptions need be made about the size of the array, as the following example shows:

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
你如我软肋 2024-10-17 03:42:30
  1. `intent(out)` 可能是一个问题,因为您必须假设传入的数组的大小。
  2. 返回数组也是一个问题,因为接收代码必须假设返回的数组的大小
  3. 指向数组的指针存在与大小相关的问题以及对指针是否关联进行假设的问题。
  4. 另一种方法是创建一个模块,并在该模块中有一个类型,其中包含可分配数组和详细说明数组大小的整数:
module mymodule
    type myvector
        double precision,allocatable::values(:)
        integer::length
    end type
end module

然后您的函数可以是:

function myvecreturner(someparam)
    use mymodule
    type(myvector)::myvecreturner
    integer::someparam

    allocate(myvecreturner%values(someparam))
    myvecreturner%length = someparam
end function

您可以愉快地传递这些 myvector 类型。只要记住在使用完数组后释放它们......

  1. `intent(out)` can be a problem as you have to make assumptions about the size of the array being passed in.
  2. returning an array is also a problem as the receiving code will have to make assumptions about the size of the array being returned
  3. pointers to arrays have the problems related to size plus the problem of making assumptions about whether the pointer is associated or not.
  4. the alternative is to create a module, and in that module have a type which contains both an allocatable array and an integer detailing the size of the array:
module mymodule
    type myvector
        double precision,allocatable::values(:)
        integer::length
    end type
end module

Then your function can be:

function myvecreturner(someparam)
    use mymodule
    type(myvector)::myvecreturner
    integer::someparam

    allocate(myvecreturner%values(someparam))
    myvecreturner%length = someparam
end function

And you can pass these myvector types around happily. Just remember to deallocate the arrays when you're done with them...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文