我正在使用旧代码工作,在这里我传递了一个数组,该数组中包含一些隐含的数据结构。是否可以创建派生类型指针并将其与此数组关联?现在假设它们都是整数。我试过了,但是说数据类型不匹配。
示例伪代码
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”是通过各种例程传递的,并且大小很大。一旦获得数组,而不是将数组及其数据结构进一步向下传递(在注释中),我想知道是否可以将其“转换”为派生类型并将其传递给它。 该数组具有数值模拟结果,这些结果被馈送到我的模块中,在其中对它们进行切片和切块并对其进行处理。将它们设置为派生类型将对我的代码有很大帮助,而不是处理偏移量并保留各种计数器的数量。我想避免复制,因此一直在寻找指针。
答案 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