前几节,基本上把fortran的函数怎么声明,怎么使用都搞完了,今天有一个很重要的任务:module:使用module来封装程序模块,通常来说,可以把程序里具备相关功能的函数以及变量封装在一起
module的语法:
module module_name
...
...
end [module[moudle_name]]
当我们在函数中要使用module的时候,就要开始声明前就用use module_name的描述来使用某一个module,另外,module的声明必须编写在前面,因为主程序和函数都会用到的。我们在module中声明的变量,如果他不是全局变量的话,在使用的时候,他们只是函数中的局部变量,而如果还想让module中的变量来传输数据,就要把这些变量声明成全局变量,或者加上一个save命令,这样在功能上也可以认为是全局变量。
先跟着书上的熟悉一下:
module global
implicit none
integer a,b
common a,b
end module
program main
use global
implicit none
a=1
b=2
call sub()
end program
subroutine sub()
use global
implicit none
write(*,*)a,b
RETURN
end
//!caution:use module_name要在implicit none之前,否则会报错
module global
implicit none
integer,save::a
end module global
program main
use global
implicit none
a=10
call sub()
write(*,*)a
stop "message"
end
subroutine sub()
! argument type, intent(inout) :: sub()
use global
implicit none
write(*,*)a
a=20
RETURN
end subroutine
实际上,我们也可以把自定义type装在module中,传参的时候只要传过去一个变量就行
eg.
module constant
implicit none
real,PARAMETER:: pi=3.14159
real,PARAMETER::G=9.81
end module
module typedef
implicit none
type player
real::angle
real::speed
real::distance
end type
end module
program main
use typedef
implicit none
integer,PARAMETER::players=5
type (player)::people(players)=(/player(30.0,25.0,0.0),&
player(45.0,20.0,0.0),&
player(35.0,21.0,0.0),&
player(50.0,27.0,0.0),&
player(40.0,22.0,0.0)/)
! real,external::Get_Distance
integer::I
do I=1,players
call Get_Distance(people(I))
write(*,"('player',I2,'=',F8.2)")I,people(I)%distance
end do
stop
end
real function Angle_To_road(angle)
use constant
implicit none
real angle
Angle_To_road=angle*pi/180.0
return
end
subroutine Get_Distance(person)
use constant
use typedef
implicit none
type(player)::person
real rad,Vx,time
real,external::Angle_To_road
rad=Angle_To_road(person%angle)
Vx=person%speed*cos(rad)
time=2.0*person%speed*sin(rad)/G
person%distance=Vx*time
return
end
module里也可以有函数
module module_name
...
...
contains
subroutine sub_name
...
end subroutine
function func_name
...
end function
end [module[moudle_name]]
//!在同一个module中的函数可以调用module中声明的所有变量
把上面的代码改改:
module constant
implicit none
real,PARAMETER:: pi=3.14159
real,PARAMETER::G=9.81
end module
module typedef
implicit none
type player
real::angle
real::speed
real::distance
end type
end module
module shoot
use constant
use typedef
implicit none
contains
real function Angle_To_road(angle)
implicit none
real angle
Angle_To_road=angle*pi/180.0
return
end function
subroutine Get_Distance(person)
implicit none
type(player)::person
real rad,Vx,time
rad=Angle_To_road(person%angle)
Vx=person%speed*cos(rad)
time=2.0*person%speed*sin(rad)/G
person%distance=Vx*time
return
end subroutine
end module
program main
use shoot
implicit none
integer,PARAMETER::players=5
type (player)::people(players)=(/player(30.0,25.0,0.0),&
player(45.0,20.0,0.0),&
player(35.0,21.0,0.0),&
player(50.0,27.0,0.0),&
player(40.0,22.0,0.0)/)
! real,external::Get_Distance
integer::I
do I=1,players
call Get_Distance(people(I))
write(*,"('player',I2,'=',F8.2)")I,people(I)%distance
end do
stop
end
输出结果是一摸一样的,我就不在贴图了,这个module写着写着,我想到了一个很好玩的事情,c++的头文件、Java、python中lib里面的包,不都是导入之后,使用里面的函数或者是变量嘛,看来代码重用这一点,早期的Fortran就已经有了,设计思路很厉害了。
至于两个不常用的命令ENTRY和Return(特别方法)就不写了,没啥用,有要使用的,可以去看书,,就和c++的重载一样,我也没见几个人用过(也或许是我层次比较低吧,用不到那么高端的,哈哈),
当你想要使用另一个文件里的东西的时候,在主程序或者函数里面写个include‘file_name.type’就可以用了。
example1.f90
program prog
implicit none
call sub()
stop
end program
include'example2.f90'
example2.f90
subroutine sub()
implicit none
write(*,*)"hello"
RETURN
end
ok,这就好了,再就没啥了,到今天截至函数就完了,明天开始学习IO操作。