【问题标题】:Over-riding FORTRAN error "array bound is not scalar integer"覆盖 FORTRAN 错误“数组边界不是标量整数”
【发布时间】:2014-03-02 20:46:00
【问题描述】:

我想知道是否可以创建一个循环,在其中我可以调用一个子例程,其中有要定义的数组,其大小随循环变量的函数而变化。我尝试如下,但得到错误“数组绑定不是标量整数”。 如何解决这个问题?

.
.
.
iloop: do i=5,24,0.5
jloop: do j=5,20 
call check(i,j,divlen,Machexit,final)
if (final.eq.1) exit iloop
enddo jloop
enddo iloop
.
.
end program

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Subroutine check(i,j,divlen,Machexit,final)
INTEGER, PARAMETER :: IVLpts=10 
real :: i,divlen,Machexit
integer :: final,j
integer :: exppts,intstrtpts,contourstrtpts,totalpts,P1,P2,P3,P4,P5,P6,P7
exppts=((j*IVLpts)+((j-1)*(IVLpts-1)))
P2=(exppts-IVLpts)
P3=(IVLpts-1)
P6=(exppts-P2)

call check2(IVLpts,i,j,divlen,Machexit,final,exppts,P2,P3,P6)

End subroutine check

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Subroutine check2(IVLpts,i,j,divlen,Machexit,final,exppts,P2,P3,P6)
Real, PARAMETER :: gamma=1.4d0,Mini=1.02d0
integer,allocatable :: expcontourpts(:),M(:),x(:),y(:)
real,allocatable :: AoverAstar(:),Mvariance(:)
allocate(expcontourpts(exppts))
allocate(M(exppts))
allocate(x(exppts))
allocate(y(exppts))
allocate(AoverAstar(P6))
allocate(Mvariance(P6))
.
.
.
End subroutine check2

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

【问题讨论】:

  • 这些过程是否在没有隐含的主机范围内?如果不是,则有一大堆东西将默认为 REAL,其中一些您正在用作数组索引...
  • 感谢您的帮助...但是,主机范围内有一个隐含的 none 规定...在此处给出的 sn-p 中包含它...。
  • 对不起,但是,像 IanH 一样,我没有看到 check2 的参数声明,特别是 exppts 和 p6 :默认情况下它们是真实值,不能用作数组维度。我还怀疑您没有将子例程放在以 IMPLICIT NONE 开头的模块中。如果它们在任何主机之外,那么它们是独立的,并且内部应该有 IMPLICIT NONE。
  • 哪一行产生错误信息?
  • 它基本上是数组定义......因为我错过了释放分配的数组......!!!所以在添加了“解除分配”部分和一些小改动之后,代码现在正在运行,尽管它显示了一些小故障......谢谢大家的所有讨论和帮助......

标签: arrays size fortran allocation


【解决方案1】:

下面是我的回答:

我想知道是否可以创建一个循环,在其中我可以调用一个子例程,其中有要定义的数组,其大小随循环变量的函数而变化。

对此的答案是“是”,但 allocate() 不是我会这样做的方式。只需使用其中一个参数作为数组维度。这是一个以非常低效的方式进行求和但使用我描述的方法的示例:

program main
  implicit none
  integer :: i, j

  do i = 1,5
    call sum_values(i,j)
    write(*,*) j
  end do

end program main

subroutine sum_values(i,j)
  implicit none
  integer, intent(in) :: i
  integer, intent(out) :: j
  integer, dimension(i) :: an_array

  an_array(1:i) = 1
  j = sum(an_array(1:i))

end subroutine sum_values

关键线是:

  integer, dimension(i) :: an_array

数组的维度在调用时在参数列表中给出。

我看到您使用的是不同的方法。这种方法应该仍然有效,但我认为我所描述的方式不太容易出错,并且适合您所要求的复杂性。确保使用“隐式无”语句,并为所有参数声明输入/输出。

【讨论】:

  • 作为维度(i)给出错误,因为我每次都会改变它的值......这就是为什么我不得不去分配 - 解除分配数组......虽然现在可以工作了是否还有其他一些小故障相关....
  • @Sathish 我发布的代码可以编译并运行,为什么它在你的代码中不起作用?变量 i 应该在你在数组维度中使用它之前声明,它应该有 intent(in) 参数。也许您的代码缺少这一点,这就是它不起作用的原因。与其他错误混在一起可能会使其变得更加困难,但是这两种方法都有效并且被其他人普遍使用。
  • @AlanSE 我很惊讶这项工作。什么编译器??
  • @george gfortran 默认情况下。我也在 ifort 和 g95 上测试过东西,但我没有检查过这个。我知道它将适用于那些编译器。这种方法是非常标准的 fortran。如果我发布的代码不适用于您的代码,请告诉我,但我很有信心它会。
  • 好的,看这里stackoverflow.com/questions/6617015/…,然后+1...有人知道哪个fortran版本引入了这种隐式分配吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多