Fortran数组指针指向标量

时间:2016-05-25 08:56:28

标签: pointers fortran reshape rank

在Fortran中,您可以使用指针重塑数组:

program working

  implicit none

  integer, dimension(:,:), pointer :: ptr
  integer, dimension(6), target :: trg

  trg = (/1,2,3,4,5,6/)
  ptr(1:2,1:3) => trg

  ! Here, you can use the 6-sized 1D array trg
  ! or the 2 by 3-sized 2D array ptr at the same time.
  ! Both have the same content (6 integers), but are only indexed
  ! differently.

  write(*,*) ptr(1,2)

end program working

该程序写入“3”,这是根据重塑规则。

同样,我试图做同样的事情,但不是1D到2D,而是0D到1D。

program not_working

  implicit none

  integer, dimension(:), pointer :: ptr
  integer, target :: trg

  trg = 1
  ptr(1:1) => trg

  ! I hoped to be able to use the scalar trg at the same time as
  ! the one-sized 1D array ptr. I thought they both have the same
  ! content, but are only indexed differently.

  write(*,*) ptr(1)

end program not_working

我希望看到“1”。但它没有编译。

Gfortran 4.9说:

  

错误:Rank重新映射目标必须是1级或者只是连续的   (1)

Ifort 14.0.2说:

  

< file> .f90:灾难性错误:内部编译器错误:   提出分段违规信号请报告此错误   在软件问题中发生的情况   报告。注意:给出的文件和行可能不是明确的原因   错误。编译中止了< file> .f90(代码1)

我不明白标量trg如何不连续,以及两个示例程序之间的根本区别是什么。

2 个答案:

答案 0 :(得分:0)

标量不是简单的连续数组,因为它根本不是数组。它是如此简单。 Gfortran检测到并抱怨,如果混淆并崩溃。但是你的代码无效,你不能将数组指针指向标量。

答案 1 :(得分:0)

数组指针被指向指向数组,因此不能指向标量(相反,我们可以使用标量指针来实现此目的)。但是如果我们肯定想使用数组指针指向标量(出于某种原因),我们可以使用c_f_pointer()这样

use iso_c_binding

integer, target :: a
integer, pointer :: p(:), q(:,:), r(:,:,:)

a = 777

call c_f_pointer( c_loc( a ), p, [1] )
call c_f_pointer( c_loc( a ), q, [1,1] )
call c_f_pointer( c_loc( a ), r, [1,1,1] )

print *, "p = ", p(:),     "with shape", shape(p)
print *, "q = ", q(:,:),   "with shape", shape(q)
print *, "r = ", r(:,:,:), "with shape", shape(r)

但这显然是一个“不安全”的功能(从某种意义上说它允许访问原始内存),如果使用错误的参数,它可能会产生错误的结果(甚至是灾难),例如:

call c_f_pointer( c_loc( a ), p, [3] )

print *, "p = ", p(:)   !! gives "p =  777  202 0" etc with garbage data

所以,除非有一些特殊的原因,我认为使用标量指针作为标量变量可能更好(更安全)......