我正在尝试编写一个程序,我希望可分配数组A
的等级为1,2或3,具体取决于我在运行时的输入。我想这样做,因为A
上的后续操作是相似的,我在模块中定义了一个接口work
,其中包含模块过程,当A
上的操作时,会给出所需的结果。
我目前正在做的是:
program main
implicit none
integer :: rank,n=10
real*8, allocatable :: A1(:)
real*8, allocatable :: A2(:,:)
read (*,*) rank
if (rank.eq.1) then
allocate (A1(n))
else if (rank.eq.2) then
allocate (A2(n,n))
end if
! operate on the array
if (rank.eq.1) then
call work(A1)
else if (rank.eq.2) then
call work(A2)
end if
end program
如果以某种方式我可以选择A
的等级,事情就会容易得多,因为不需要if
语句。也许这是不可能的,但所有的帮助都表示赞赏。
答案 0 :(得分:2)
下一个Fortran标准(2015)的select rank
结构类似于select case
。我的示例在假定等级虚拟变量的select case
内在函数上使用rank
构造。
module my_type
use, intrinsic :: iso_fortran_env, &
ip => INT32, &
wp => REAL64
implicit none
private
public :: MyType
type MyType
real (wp) :: rank0
real (wp), allocatable :: rank1(:)
real (wp), allocatable :: rank2(:,:)
real (wp), allocatable :: rank3(:,:,:)
contains
procedure :: create => create_my_type
procedure :: destroy => destroy_my_type
end type MyType
contains
subroutine create_my_type(this, array)
! calling arguments
class (MyType), intent (in out) :: this
real (wp), intent (in) :: array(..) !! Assumed-rank dummy variable
! local variables
integer (ip), allocatable :: r(:)
select case(rank(array))
case (0)
return
case (1)
r = shape(array)
allocate( this%rank1(r(1)) )
case (2)
r = shape(array)
allocate( this%rank2(r(1), r(2)) )
case (3)
r = shape(array)
allocate( this%rank3(r(1), r(2), r(3)) )
case default
error stop 'array must have rank 0,1,2, or 3'
end select
! Release memory
if (allocated(r)) deallocate( r )
end subroutine create_my_type
subroutine destroy_my_type(this)
! calling arguments
class (MyType), intent (in out) :: this
if (allocated(this%rank1)) deallocate( this%rank1 )
if (allocated(this%rank2)) deallocate( this%rank2 )
if (allocated(this%rank3)) deallocate( this%rank3 )
end subroutine destroy_my_type
end module my_type
program main
use, intrinsic :: iso_fortran_env, only: &
ip => INT32, &
wp => REAL64
use my_type, only: &
MyType
implicit none
type (MyType) :: foo
real (wp) :: a0, a1(42), a2(42,42), a3(42,42,42)
print *, rank(a0)
print *, rank(a1)
print *, rank(a2)
print *, rank(a3)
! Allocate array of rank 3
call foo%create(a3)
print *, rank(foo%rank3)
print *, shape(foo%rank3)
print *, size(foo%rank3)
! Release memory
call foo%destroy()
end program main
答案 1 :(得分:1)
将数组声明为rank 3。如果需要较低级别的数组,请将相关的尾随维度分配为大小为一。
real, allocatable :: array(:,:,:)
...
select case (desired_rank)
case (1) ; allocate(array(n,1,1))
case (2) ; allocate(array(n,n,1))
case (3) ; allocate(array(n,n,n))
case default ; error stop 'bad desired rank'
end select
然后,您可以使用数组部分来获得与您所需排名一致的array
的连续切片。或者,编写对数组进行操作的相关过程以获得三级参数,并使它们了解更高维度的大小一个范围的含义。