我想知道如何分配两个指针,一个指向复杂的3d数组的实部,另一个分配给Fortran中同一数组的虚部。
假设我已经这样定义了一个3d数组:
复杂* 16,尺寸(:,:,:),可分配,目标:: vftmp
,我想分配一个指向vftmp(2,1,1)实部的指针和一个指向vftmp(2,1,1)虚部的指针。有人可以帮我摘录吗?谢谢。
答案 0 :(得分:1)
我希望可能出现以下情况
Local
,但似乎不是(或者对于非常新的编译器来说可能...?)所以下面是一种变通方法:
1)如果目标是获取复杂数组中单个元素的Re和Im部分的(标量)指针,我猜我们可以使用real, pointer :: re
complex, target :: z
re => z % re
! or
real, pointer :: re(:,:,:)
complex, target :: z(2,3,4)
re => z(:,:,:) % re
这样
c_f_pointer
结果(gfortran-8.2):
module testmod
contains
subroutine getreim_ptr( z, re, im )
use iso_c_binding
implicit none
complex, target, intent(in) :: z
real, pointer :: re, im, buf(:)
call c_f_pointer( c_loc( z ), buf, [ 2 ] )
re => buf( 1 )
im => buf( 2 )
end subroutine
end module
program main
use testmod
implicit none
complex :: z( 2, 3 )
real, pointer :: re, im
!! Test array.
z = 0.0
z( 1, 1 ) = ( 1.0, -1.0 )
!! Get pointers for the Re/Im parts of z(1,1).
call getreim_ptr( z( 1, 1 ), re, im )
print *, "z(1,:) = ", z(1,:)
print *, "z(2,:) = ", z(2,:)
print *, "re = ", re
print *, "im = ", im
end
2)如果目标是获取整个复杂数组的数组指针,我想我们可以使用秩重映射指针分配(指向具有恒定间隔的非连续内存)。例如,在2D情况下(为简单起见),
z(1,:) = (1.00000000,-1.00000000) (0.00000000,0.00000000) (0.00000000,0.00000000)
z(2,:) = (0.00000000,0.00000000) (0.00000000,0.00000000) (0.00000000,0.00000000)
re = 1.00000000
im = -1.00000000
其中re( 1:n1, 1:n2 ) => buf( 1::2 )
im( 1:n1, 1:n2 ) => buf( 2::2 )
和re
是2D数组指针,而im
是一个实际的1D数组指针,它指向可分配的2D复杂数组(通过buf
)。一个最小的例子可能是这样的:
c_f_pointer
结果(gfortran 8.2):
module testmod
contains
subroutine getreim_ptr2d( zarr, re, im )
use iso_c_binding
implicit none
complex, allocatable, target, intent(in) :: zarr(:,:)
real, pointer :: re(:,:), im(:,:), buf(:)
integer :: n1, n2
n1 = size( zarr, 1 )
n2 = size( zarr, 2 )
call c_f_pointer( c_loc( zarr ), buf, [ size(zarr) * 2 ] )
re( 1:n1, 1:n2 ) => buf( 1::2 )
im( 1:n1, 1:n2 ) => buf( 2::2 )
end subroutine
end module
program main
use testmod
implicit none
complex, allocatable :: zarr(:,:)
real, pointer :: re(:,:), im(:,:)
integer i
!! Prepare a test array (zarr).
allocate( zarr( 2, 3 ) )
zarr(1,:) = [( complex( 100 + i, -100 -i ), i=1,3 )]
zarr(2,:) = [( complex( 200 + i, -200 -i ), i=1,3 )]
print *, "shape( zarr ) = ", shape( zarr )
print *, "zarr(1,:) = ", zarr(1,:)
print *, "zarr(2,:) = ", zarr(2,:)
call getreim_ptr2d( zarr, re, im )
print *
print *, "shape( re ) = ", shape( re )
print *, "re(1,:) = ", re(1,:)
print *, "re(2,:) = ", re(2,:)
print *
print *, "shape( im ) = ", shape( im )
print *, "im(1,:) = ", im(1,:)
print *, "im(2,:) = ", im(2,:)
end program
下面是一些我们可以在网上找到的材料:
Fortran 2003 (N1597)的新功能:3.7“指针分配”
“ ......允许重排第一级数组的元素:
shape( zarr ) = 2 3
zarr(1,:) = (101.000000,-101.000000) (102.000000,-102.000000) (103.000000,-103.000000)
zarr(2,:) = (201.000000,-201.000000) (202.000000,-202.000000) (203.000000,-203.000000)
shape( re ) = 2 3
re(1,:) = 101.000000 102.000000 103.000000
re(2,:) = 201.000000 202.000000 203.000000
shape( im ) = 2 3
im(1,:) = -101.000000 -102.000000 -103.000000
im(2,:) = -201.000000 -202.000000 -203.000000
映射按数组元素顺序进行,并且目标数组必须足够大。边界可以是任何标量整数表达式。排名第一的数组的限制是因为指针数组不需要占用连续的存储空间:
p(1:m,1:2*m) => a(1:2*m*m)
但在第一种情况下所有间隙的长度都相同。”
Fortran 2003扩展:5.4.3排名重映射指针分配(this page)
“ ...此功能允许多维指针指向一维对象。例如:
a => b(1:10:2)
请注意,在进行秩重新映射时,必须为所有维度明确指定上下限的值,没有默认值。”