在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
如何不连续,以及两个示例程序之间的根本区别是什么。
答案 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
所以,除非有一些特殊的原因,我认为使用标量指针作为标量变量可能更好(更安全)......