子程序忽略模块中的类型声明

时间:2016-07-18 21:27:28

标签: fortran

我在模块中创建了一个类型model,然后声明了一个具有该类型的变量md。在模块中包含的子例程中,忽略上面md的声明,我必须再次明确声明它。

在主程序中,我不需要声明md的类型,use语句似乎有效。任何人都可以解释为什么子程序忽略md的类型声明?

这是代码。我在Linux上使用gfortran编译器。

program main
  use struc_model
  call mod_gen(md)
  do i=1, md%ndof
    write(*,*) 'row =', i
    write(*,*) 'm=', md%m(i,:)
  end do  
end

module struc_model
  type model
    integer :: ndof
    real*8, allocatable, dimension(:,:) :: m
  end type
  type (model) :: md
  contains
  subroutine mod_gen(md)
  ! for some reason have to declare type of md again
  ! declaration above is ignored
    type (model) :: md  
    md%ndof=4
    allocate(md%m(md%ndof,md%ndof))
    md%m=0.d0
    do i=1, md%ndof
      md%m(i,i)=1.d0
    end do
  end subroutine
end module

1 个答案:

答案 0 :(得分:5)

这里有三个感兴趣的术语:使用关联主机关联参数关联。您可以通过其他资源详细了解这些内容,但我会在此处进行解释。

首先看模块。为了清楚起见,我将把变量设为整数类型。这是一个简单的程序

module mod
  implicit none
  integer i
end module mod

program prog
  use mod
  implicit none
  print *, i       ! i is use associated
end program prog

在这里,我们并未说明i的类型是通过模块声明的,我们说i是来自模块的变量(和它的类型来自于)。

现在看一个简化的模块:

module mod
  implicit none
  integer i

contains

  subroutine sub(i)
    integer i
  end subroutine

end module mod

那么,为什么我需要在子例程integer i中使用sub声明?这是因为该子例程中的i出现在参数列表中,是伪参数。伪参数需要在其范围内指定子类型的类型。在子例程中,i的引用是伪参数而不是模块变量:模块变量不可访问。

如果我的程序看起来像

  use mod
  call sub(i)
end program

我正在做的是将已经使用关联的模块变量i传递给子例程sub作为其伪参数(通过参数关联)。 / p>

现在,如果我想修改模块子程序中的模块变量,我可以改为使用主机关联

module mod
  implicit none
  integer i

contains

  subroutine sub()  ! No dummy argument i, references in here are to the module's i
  end subroutine

end module mod

program prog
  use mod
  implicit none

  call sub   ! No argument for the module's own variable
end program prog

在该模块中,子程序i指的是模块变量。

但我怀疑你的意思是在程序的范围内有一个变量传递给子程序。回到你的术语:

module struc_model
  type model
    integer :: ndof
    real*8, allocatable, dimension(:,:) :: m
  end type
  contains
  subroutine mod_gen(md)
    type (model) :: md  
    md%ndof=4
    allocate(md%m(md%ndof,md%ndof))
    md%m=0.d0
    do i=1, md%ndof
      md%m(i,i)=1.d0
    end do
  end subroutine
end module

program main
  use struc_model
  type (model) :: md    ! A variable within the program's scope
  call mod_gen(md)      ! Argument associated with the subroutine's dummy
  do i=1, md%ndof
    write(*,*) 'row =', i
    write(*,*) 'm=', md%m(i,:)
  end do  
end

总结

module struc_model
  type model
    integer :: ndof
    real*8, allocatable, dimension(:,:) :: m
  end type
  type (model) :: md
end module

声明一个模块变量md并且没有声明所有名为md的变量都是type(model)