Arrays 函数中传递的Fortran数组形状更改
我在一个程序块中声明并填充了一个数组,该程序块被传递给模块内的函数。然而,程序块中的数组形状与功能块中的数组形状不同,这在实践中会导致错误。下面是一些用于说明的简化代码:Arrays 函数中传递的Fortran数组形状更改,arrays,fortran,Arrays,Fortran,我在一个程序块中声明并填充了一个数组,该程序块被传递给模块内的函数。然而,程序块中的数组形状与功能块中的数组形状不同,这在实践中会导致错误。下面是一些用于说明的简化代码: program prgQuad use modPoint2D, only: Point2D use modQuadrature, only : QuadIntegrateTri2D implicit none ! the array in question type( Point2D
program prgQuad
use modPoint2D, only: Point2D
use modQuadrature, only : QuadIntegrateTri2D
implicit none
! the array in question
type( Point2D ), dimension( : ) :: pts( 1: 3 )
real :: res
! populate the points
call pts( 1 ) % set( 0.0, 0.0 )
call pts( 2 ) % set( 1.0, 0.0 )
call pts( 3 ) % set( 1.0, 1.0 )
write( *, * ) shape( pts ) ! prints '3'
! use the points
res = QuadIntegrateTri2D( pts )
end program prgQuad
在正交中:
function QuadIntegrateTri2D( pts ) result( integral )
class( Point2D ), dimension( : ), intent( in ) :: pts( 1: 3 )
real :: integral
! other vars go here
write( *, * ) shape( pts ) ! prints '4'
! actual function code goes here
end function QuadIntegrateTri2D( pts )
我肯定错过了什么。我不知道为什么阵列的形状会改变。我知道Fortran是通过引用传递的,所以程序块和函数正在查看同一块内存。任何关于形状变化原因的见解都值得赞赏!谢谢
modPoint2D:
module modPoint2D
type Point2D
real( rp ) :: x, y
contains
procedure :: set => SetPoint2D
end type
contains
subroutine SetPoint2D( self, x, y )
class( Point2D ), intent( out) :: self
real( rp ), intent( in ) :: x, y
self % x = x
self % y = y
end subroutine SetPoint2D
end module modPoint2D
pts
的声明确实非常奇特。下面的代码使用点数组的正确形状按照预期进行编译和运行
module modPoint2D
type :: Point2D
real :: x,y
contains
procedure, pass :: set
end type
contains
subroutine set(pnt, px, py)
class(Point2D), intent(out) :: pnt
real, intent(in) :: px, py
pnt%x = px
pnt%y = py
end subroutine
end module
module modQuadrature
use modPoint2D
contains
function QuadIntegrateTri2D( pts ) result( integral )
class( Point2D ), dimension( : ), intent( in ) :: pts
real :: integral
! other vars go here
write( *, * ) shape( pts ) ! prints '3'
! actual function code goes here
integral = 0
end function
end module
program prgQuad
use modPoint2D, only: Point2D
use modQuadrature, only : QuadIntegrateTri2D
implicit none
! the array in question
type( Point2D ), dimension(:) :: pts(1:3)
real :: res
call pts( 1 ) % set( 0.0, 0.0 )
call pts( 2 ) % set( 1.0, 0.0 )
call pts( 3 ) % set( 1.0, 1.0 )
write( *, * ) shape( pts ) ! prints '3'
! use the points
res = QuadIntegrateTri2D( pts )
end program
pts
的声明确实非常奇特。下面的代码使用点数组的正确形状按照预期进行编译和运行
module modPoint2D
type :: Point2D
real :: x,y
contains
procedure, pass :: set
end type
contains
subroutine set(pnt, px, py)
class(Point2D), intent(out) :: pnt
real, intent(in) :: px, py
pnt%x = px
pnt%y = py
end subroutine
end module
module modQuadrature
use modPoint2D
contains
function QuadIntegrateTri2D( pts ) result( integral )
class( Point2D ), dimension( : ), intent( in ) :: pts
real :: integral
! other vars go here
write( *, * ) shape( pts ) ! prints '3'
! actual function code goes here
integral = 0
end function
end module
program prgQuad
use modPoint2D, only: Point2D
use modQuadrature, only : QuadIntegrateTri2D
implicit none
! the array in question
type( Point2D ), dimension(:) :: pts(1:3)
real :: res
call pts( 1 ) % set( 0.0, 0.0 )
call pts( 2 ) % set( 1.0, 0.0 )
call pts( 3 ) % set( 1.0, 1.0 )
write( *, * ) shape( pts ) ! prints '3'
! use the points
res = QuadIntegrateTri2D( pts )
end program
您是否已使用所有检查选项进行编译,以确保某个地方没有不可靠的访问?除此之外,你能为我们准备一个完整的例子吗?看,这很奇怪。但同样奇怪的是,函数参数的大小/形状有两个规范
pts
。通常我们(旧的Fortran程序员)只指定一次,例如,class(Point2D)、dimension(:)、intent(in)::pts
——作为假定的形状参数。应该注意的是,伪参数pts
类似于pts(1:3)
,完全独立于主程序中名为pts
的实体(只要后者至少有三个元素)。因此,如果该函数中的shape(pts)
给出了不同的结果,那么编译器或代码中的某个地方就会出现错误。感谢您的回复,所有。我修改了我的函数以接受real,intent(in)::pts(1:3)
报告了正确的形状。然后我将其修改为类型(Point2D),意图(in)::pts(1:3)
而不是类(Point2D)
函数再次报告了正确的形状。因此,我认为我已经将其缩小为类
标识符问题。我正在使用gcc 6.1.0中的gfortran进行编译。能否请您包含set()的定义
您是否已使用所有检查选项进行编译,以确保某个地方没有不可靠的访问?除此之外,您能否为我们准备一个完整的示例?请参阅。这非常奇怪。但也奇怪的是,您有两个函数参数的大小/形状规格pts
。通常是我们(旧Fortran程序员)只需将其指定一次,例如,class(Point2D)、dimension(:)、intent(in)::pts
——作为假定的形状参数。应该注意的是,伪参数pts
类似于pts(1:3)
,完全独立于主程序中名为pts
的实体(只要后者至少有三个元素)。因此,如果该函数中的shape(pts)
给出了不同的结果,则编译器或代码中的某个地方会出现错误。感谢您的回复,所有。我修改了我的函数以接受real,intent(in)::pts(1:3)
并报告了正确的形状。然后我修改了它,采用类型(Point2D),intent(in)::pts(1:3)
而不是class(Point2D)
,函数再次报告了正确的形状。因此我认为我已将其缩小为class
标识符问题。我正在使用gcc 6.1.0中的gfortran进行编译。您能包含set()的定义吗
您的意思是,在完整的示例中,在主程序中使用类(Point2D)、维度(:)、意图(in)::pts(1:3)
会显示问题的问题吗?类型(Point2D)、维度(:)::pts(1:3)
会生成正确的输出。我将编辑答案。没有理由指定类(Point2D),维度(:),意图(in)::pts(1:3)
inquadigratetri2d()
你是说在你的完整示例中,拥有类(Point2D),维度(:),意图(in)::pts(1:3)
展示了问题的问题吗?类型(Point2D),维度(:)::pts(1:3)
在主程序中生成正确的输出。我将编辑答案。没有理由指定类(Point2D)、维度(:)、意图(in)::pts(1:3)
在quadigratetri2D()中