将公共块数组大小传递给 Fortran 中的子例程

Pass Common block array size to subroutine in Fortran

我想将数组维度作为虚拟变量传递给子例程。数组本身位于公共块上。这是代码:

PROGRAM test
integer i, nn
integer PARAMETER(Nt=10)
real x(Nt), y(nt), z(Nt)
Common /Bdat/ z
nn=Nt
do i=1,Nt
x(i)=i+1
z(i)=i-1
enddo
call estimate(x,y,nn)
print*, y
return
end

subroutine estimate(x,y,jj)
integer i,jj
real x(jj), y(jj), zq(jj)
COMMON /Bdat/ zq
do i=1, jj
y(i)=x(i)+zq(i)
enddo
return
end

这是我从子程序中得到的错误:

real x(jj), y(jj), zq(jj)
                      1

错误:在此上下文中 (1) 处的变量 'jj' 必须是常量

如果有人能解决这个问题,我将不胜感激。

您遇到范围问题。阅读:Scope in Fortran. That is, your subroutine estimate needs access to the variable Nt which you need to pass as an additional argument, or you can move the entire subroutine inside your program using the contains statement. This will allow your program to run successfully, but I highly encourage you to abstain from using common blocks. If you cannot avoid them due to legacy codes see: Improve your FORTRAN 77 programs using some Fortran 90 features

尝试改用模块:

    module bdat

      implicit none

      private
      public :: NT, z

      integer, parameter :: NT = 10
      real               :: z(NT) 

    end module bdat

    module my_sub

      use bdat, only: &
           zq => z ! You're free to rename the variable

      implicit none
      private
      public :: estimate

    contains

      subroutine estimate(x,y)
        ! calling arguments
        real, intent (in) :: x(:)
        real, intent (out) :: y(:)

        ! local variables
        integer :: i, jj

        jj = size(x)

        do i=1, jj
           y(i)=x(i)+zq(i)
        end do

      end subroutine estimate

    end module my_sub

    program test

      use bdat, only: &
           NT, z

      use my_sub, only: &
           estimate

      implicit none

      integer :: i
      real :: x(NT), y(NT)

      do i=1,NT
         x(i)=i+1
         z(i)=i-1
      end do

      call estimate(x,y)

      print *, y

    end program test