在编写程序时,我们都希望尽量将程序模块化,即把一个复杂工作细分成多个简单的过程。对于科学计算来说就不免要涉及到文件的读取,有时文件格式较复杂,如果都写在主函数program中,会使代码显得非常凌乱,因此我们希望将读写过程写在一个子过程中。在我的工作过程中,经常会碰到如下的
数据格式:

对于这种在编写时,数据个数未知的情况通常我们要适用动态数组,在读取第一行的n后,从1到n循环
读取数据:
program www_fcode_cn
implicit none
integer, allocatable :: array(:)!动态数组
integer :: n
integer :: i
open(100, file='INPUT.txt')
read(100, *) n
allocate(array(n))!获取到数据个数后分配内存
do i=1, n
read(100, *) array(i)!读取数据
enddo
close(100)
!用array数组做一些计算
call system("pause")
end program www_fcode_cn
正如我上面所说,如果输入文件较复杂,我会更喜欢将读文件过程分离出来,使代码结果更清晰:
program www_fcode_cn
implicit none
integer, allocatable :: array(:)
integer :: n
integer :: i
call readFile(n, array)!把未分配内存的数组传入,未知的数据个数n传入
write(*, *) (array(i), i=1,n)
call system("pause")
end program www_fcode_cn
subroutine readFile(n, array)
integer :: n
integer, allocatable :: array(:)!此处仍然要声明allocatable
integer :: i
read(*, *) n
open(100, file='INPUT.txt')
read(100, *) n
allocate(array(n))
do i=1, n
read(100, *) array(i)
enddo
close(100)
end subroutine readFile
这段代码看起来逻辑没有什么错误,但编译后就会出现错误提示
||Error: Dummy argument 'array' of procedure 'readfile' has an attribute that requires an explicit interface for this procedure|
显然编译器不支持这样的操作,解决这个问题有两种方式
方法一:Interface
这个方法是利用了Fortran的Interface语法,在调用函数readFile的地方加入Interface(类似c语言的函数声明,不过是在函数内的函数声明),只要对上面代码略加修改即可。
program www_fcode_cn
! use myModule
implicit none
integer, allocatable :: array(:)
integer :: n
integer :: i
!---------------------------------------------------------------------------
!------------------------------------------------------------------INTERFACE
interface
subroutine readFile(n, array)
integer :: n
integer, allocatable :: array(:)
end subroutine
end interface
!------------------------------------------------------------------INTERFACE
!---------------------------------------------------------------------------
call readFile(n, array)
write(*, *) (array(i), i=1,n)
call system("pause")
end program www_fcode_cn
subroutine readFile(n, array)
integer :: n
integer, allocatable :: array(:)
integer :: i
read(*, *) n
open(100, file='INPUT.txt')
read(100, *) n
allocate(array(n))
do i=1, n
read(100, *) array(i)
enddo
close(100)
end subroutine readFile
这种方法有一个缺点就是,如果你在几个不同的过程里都调用了readFile,那么在这些过程中都要加
入interface块,过于麻烦,而第二种方法就很好的解决了这个问题。
方法二:Module
Fortran的Module非常好用,我经常用他来包含一些常用的过程或计算时用到的常量。在本文所讨论的
问题是,也要借助Module来实现,具体方法也很简单:把readFile放在Module中,所有使用了
readFile的过程或函数只需在开头加上一句 use xxxModule。
program www_fcode_cn
use myModule !这句一定要有
implicit none
integer, allocatable :: array(:)
integer :: n
integer :: i
call readFile(n, array)
write(*, *) (array(i), i=1,n)
call system("pause")
end program www_fcode_cn
在另一个f90文件中:
module myModule
contains
subroutine readFile(n, array)
integer :: n
integer, allocatable :: array(:)
integer :: i
read(*, *) n
open(100, file='INPUT.txt')
read(100, *) n
allocate(array(n))
do i=1, n
read(100, *) array(i)
enddo
close(100)
end subroutine
end module myModule
这样就完美解决了。
编译器:Gfrotran
IDE:Code::Blocks



