在fortran中传递指针参数

时间:2014-08-30 23:30:32

标签: pointers fortran fortran90 gfortran

我想知道编写以下代码的正确方法是什么?

PROGRAM foo

  INTEGER :: x
  REAL(KIND=8), TARGET, DIMENSION(0: 10) :: array
  REAL(KIND=8), POINTER, DIMENSION(:) :: ptr

  ptr => array

  CALL bar(ptr)

END PROGRAM foo

SUBROUTINE bar (ptr)

  REAL(KIND=8), POINTER, DIMENSION(:) :: ptr                                                                                                                                                                                                                  
  INTEGER x
  DO x =0, 10
    ptr(x) = 2 // seg faults
  ENDDO

END SUBROUTINE bar

如果我在ptr中将bar声明为REAL(KIND=8), DIMENSION(0:10),则此功能正常。但总的来说,我可能不知道传入数组的大小,那么有没有办法将ptr声明为指向某个数组的指针?我正在使用gfortran

进行编译

2 个答案:

答案 0 :(得分:2)

如果一个过程的伪参数是一个指针,那么任何调用范围都需要一个显式接口。

(有很多东西需要显式接口,指针虚拟只有一个。)

您可以通过在主程序中放置子程序的接口块来自己提供该显式接口。一个替代的,远,远,更好的选择是将子例程放在一个模块中,然后在主程序中使用该模块。第三种方法是使子程序成为调用范围的内部过程。

从Fortran 2003开始,如果你打算将指针指向不同的东西,你应该只使用指针。如果你只是将指针用于一些真正表现得像值的东西,那么你应该使用allocatables。

答案 1 :(得分:2)

这取决于你对“正确”方式的意思。正如IanH已经pointed out,你需要一个显式接口(最好通过在模块中打包)并使用allocatables而不是指针,如果可能的话。

我还要补充一点,如果您不想在子程序中更改数组的分配状态,但只想操纵其元素,那么在子程序中使用一个简单的假定形状数组。下面你会找到一个有效的例子。还有一些事项需要注意:

  • 不要使用real(kind=8),因为并非所有编译器都使用字节数作为实数的种类。如果您想要双精度准确度,请按以下方式明确要求。

  • 如果您只想填充具有常量值的数组,请按以下简单方式执行:array(:) = 2.0_dp

这里的例子是:

module accuracy
  implicit none

  integer, parameter :: dp = kind(1.0d0)

end module accuracy


module barmodule
  use accuracy
  implicit none

contains

  subroutine  bar(array)
    real(dp), intent(inout) :: array(:)

    integer :: ii

    do ii = 1, size(array)
      array(ii) = ii
    end do

  end subroutine bar

end module barmodule


program foo
  use accuracy
  use barmodule
  implicit none

  real(dp), dimension(0:10) :: array
  call bar(array)

end program foo