Fortran学习11:函数5

前几节,基本上把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操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值