在Fortran子例程中分配数组

4

我需要在Fortran程序中从文件中读取大量数据。由于数据大小是可变的,因此我想动态分配数组。我的想法是编写一个子例程来读取所有数据并分配内存。程序的简化版本如下:

  program main

  implicit none
  real*8, dimension(:,:), allocatable :: v
  integer*4 n

  !This subroutine will read all the data and allocate the memory 
  call Memory(v,n)

  !From here the program will have other subroutines to make calculations

  end


  subroutine Memory(v,n)

  implicit none
  real*8, dimension(:,:), allocatable :: v
  integer*4 n,i

  n=5
  allocate(v(n,2))
  do i=1,n
  v(i,1)=1.0
  v(i,2)=2.0 
  enddo

  return
  end subroutine Memory

这个程序给我返回了以下错误信息:
Error: Dummy argument 'v' of procedure 'memory' at (1) has an attribute that requieres an explicit interface for this procedure

这是构建此类程序的正确方式吗?如果是,我该如何解决错误?

谢谢。

1个回答

9
假设您有一个包含程序和子程序的单个源文件,正如您的帖子所示,最简单的修复方法是替换包含该语句的行。
end

带有包含该语句的一行。
contains

在源文件的末尾添加一行包含该语句的代码:“并在源文件末尾写入”。
end program

(是的,关键字program不是必需的,但它很有用。)
您的编译器报告的问题是,按照您构造代码的方式,程序不知道子例程memory的接口,该接口在Fortran术语中是隐式的。当您想调用一个子例程并传入或传出可分配数组时,该子例程必须具有显式接口。
提供显式接口的方法有几种。其中一种是,如我所示,将子例程包含在程序中。另一种更有用的方式是,在模块中编写子例程,并在要使用它们的程序中使用关联-使用它们。阅读您的Fortran教程涵盖的moduleuse语句的部分。
至少还有一种选择,但对于初学者来说并不可取,我不会在这里提到它。
而且,在我写作时,请了解并使用关键字intent来指定传递给子例程的参数是读取、写入还是两者都有。这是安全编程的重要辅助工具,您喜欢的Fortran资源将详细解释。

谢谢!在我的实际程序中,我有多个文件,我会尝试模块化的方法。 - Msegade
5
如果我可以提另一个建议-尽量“忘掉”非标准的real8和integer4语法,它会限制灵活性。一个受欢迎的方法是定义一个模块KINDS,使用SELECTED_INT_KIND和SELECTED_REAL_KIND声明一系列PARAMETER常量来指定您要使用的类型,例如SP和DP,然后在声明中使用REAL(DP)。我同意Mark的看法,模块是您在这里最好的选择。 - Steve Lionel
另外请注意,上面定义的所有变量“包含”都将是全局的,并且可以在“包含”下的所有子程序中访问。因此,您可以在“包含”下编写一个subroutine main(),其中包含整个程序。并且在“包含”之前只放置“implicit none”,全局数组的定义和“call main()”。 - Jonatan Öström

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接