是否可以将Fortran派生数据类型指针指向固有数据类型?

时间:2019-01-24 13:15:56

标签: fortran

我正在使用旧代码工作,在这里我传递了一个数组,该数组中包含一些隐含的数据结构。是否可以创建派生类型指针并将其与此数组关联?现在假设它们都是整数。我试过了,但是说数据类型不匹配。

示例伪代码

subroutine process_array(a)
  integer,target,intent(in) :: a(*)
  ! defined elsewhere
  ! type struct
  !   integer :: b
  !   integer :: c
  !   integer :: d
  ! end type struct
  type(struct), pointer :: temp_struct(:)

  temp_struct=>a(1:size(a))
  ! do something

end subroutine process_array

此数组“ a”是通过各种例程传递的,并且大小很大。一旦获得数组,而不是将数组及其数据结构进一步向下传递(在注释中),我想知道是否可以将其“转换”为派生类型并将其传递给它。 该数组具有数值模拟结果,这些结果被馈送到我的模块中,在其中对它们进行切片和切块并对其进行处理。将它们设置为派生类型将对我的代码有很大帮助,而不是处理偏移量并保留各种计数器的数量。我想避免复制,因此一直在寻找指针。

1 个答案:

答案 0 :(得分:0)

[注:当目标数组很大时,以下方法会为指针变量使用大量内存,因此根据情况,它可能不是很好...其他方法可能会更好。]

尽管不可能将派生类型直接指向原始类型的数组,但是如何使包含指针的派生类型并通过函数设置它们呢?例如...

FILTER_VALIDATE_INT

结果(gfortran-8 test.f90)

FILTER_SANITIZE_NUMBER_INT

其他说明:

  • 我们还可以使用module testmod implicit none type view_t integer, pointer :: nx, ny, vec(:) endtype contains function makeview( arr ) result( v ) integer, target, intent(in) :: arr( : ) type(view_t) :: v v % nx => arr( 1 ) v % ny => arr( 2 ) v % vec => arr( 3 : 4 ) endfunction endmodule program main use testmod implicit none integer arr( 4 * 2 ), i, offset type(view_t) :: v, views( 2 ) ! We suppose that arr(:) consists of 2 blocks of data (each have 4 integers). arr(:) = [( i, i = 1, size(arr) )] !! dummy data print *, "arr = ", arr ! Create a view for the first block of arr(:). v = makeview( arr( 1 : 4 ) ) print *, "v % {nx, ny} = ", v % nx, v % ny print *, "v % vec = ", v % vec ! Create a set of views for all the blocks of arr(:). do i = 1, 2 offset = (i - 1) * 4 views( i ) = makeview( arr( offset + 1 : offset + 4 ) ) enddo arr( 7:8 ) = arr( 7:8 ) * 100 !! modify the original array print *, "views( 1 ) % vec = ", views( 1 ) % vec print *, "views( 2 ) % vec = ", views( 2 ) % vec end 来省略视图变量( arr = 1 2 3 4 5 6 7 8 v % {nx, ny} = 1 2 v % vec = 3 4 views( 1 ) % vec = 3 4 views( 2 ) % vec = 700 800 )的声明,但是在这种情况下,我们似乎无法修改associate等(可能是因为它是一个表达式)。
foo
  • 另一种方法可能是使用具有非指针组件的派生类型并使用foo % vec。如果所有组件都是默认的基本类型(例如,所有默认整数),则此方法似乎可行,但由于填充(不是很确定...),否则可能会出现问题(例如,整数精度和双精度的混合)。因此,我认为这种方法可能有用,但需要多加注意(“不安全”)。
    associate( foo => makeview( arr( 1:4 ) ) )
      print *, foo % vec  !! OK
      ! foo % vec = 100   !! error
    endassociate