由于某种原因,我需要将 Fortran 指针传递给子例程。子程序位于模块内部,主程序使用该模块来确保显式接口(interface)。
我的问题是,我应该在子例程的虚拟参数上指定什么属性才能接收传入的指针?
我尝试了下面的代码。
module aaa
contains
integer*4 function print_ptr_arr_1( ptr )
implicit none
integer*4, intent(in), pointer :: ptr(:)
print *, 'as pointer'
print *, size(ptr)
print '(10i3)', ptr
print *
end function print_ptr_arr_1
integer*4 function print_ptr_arr_2( ptr )
implicit none
integer*4, intent(in), target :: ptr(:)
print *, 'as target'
print *, size(ptr)
print '(10i3)', ptr
print *
end function print_ptr_arr_2
integer*4 function print_ptr_arr_3( ptr )
implicit none
integer*4, intent(in) :: ptr(:)
print *, 'as assumed shape array'
print *, size(ptr)
print '(10i3)', ptr
print *
end function print_ptr_arr_3
end module aaa
和
program main
use aaa
implicit none
integer*4 :: i1, ierr
integer*4, target :: arr(10)
integer*4, pointer :: ptr_arr(:)
do i1 = 1, 10
arr(i1) = i1
end do
ptr_arr => arr
ierr = print_ptr_arr_1( ptr_arr )
ierr = print_ptr_arr_2( ptr_arr )
ierr = print_ptr_arr_3( ptr_arr )
nullify( ptr_arr )
end program main
模块 aaa 中的三个子例程显示正确的输出,如下所示。
sj2734@sonaram:~/work/practice/fortran_pointer$ ./a.out
as pointer
10
1 2 3 4 5 6 7 8 9 10
as target
10
1 2 3 4 5 6 7 8 9 10
as assumed shape array
10
1 2 3 4 5 6 7 8 9 10
sj2734@sonaram:~/work/practice/fortran_pointer$
什么是正确的,什么是不正确的?或者说,这些都正确吗?
最佳答案
这取决于您将如何使用传递给函数的内容。你需要它作为一个指针吗?然后赋予它pointer
属性。需要在函数中用另一个指针指向它吗?然后,为其指定 target
属性。虚拟参数将采用您赋予它的任何属性。
如果将其声明为指针
,那么您可以将其用作指针并分配/指向函数内的新内容。
如果您将其声明为目标
,则函数内的其他指针可以指向它,但您将无法用它指向目标
,因为它不是一个指针。
如果您只想将其视为数组,那么您可以将其声明为假定大小的数组并将其视为常规数组,但您将无法像使用它一样使用它它具有pointer
或target
属性。
所以从某种程度上来说,他们是没问题的。这取决于上下文。但是,除非您出于特定原因确实需要它成为指针或目标,并且您只是将其视为数组,否则最好将其声明为假定大小的数组,以避免潜在的内存问题。
关于pointers - 如何将 Fortran 指针传递给子例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34960775/