Fortran 数组指向标量的指针



在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"。但它不编译。

格福特兰 4.9 说:

错误:排名重新映射目标必须为排名 1 或只是连续 (1)

伊福特 14.0.2 说:

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

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

标量不是简单的连续数组,因为它根本不是一个数组。就这么简单。格福特兰察觉到并抱怨,伊福特很困惑,崩溃了。但是您的代码无效,您不能将数组指针指向标量上。

数组指针旨在指向数组,因此不能指向标量(相反,我们可以为此目的使用标量指针)。但是,如果我们肯定想使用数组指针来指向标量(出于某种原因),我们可以使用 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

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

最新更新