Fortran moudle/subroutine/function 的用法示例

吐槽:作为一个Fortran 语言的初学者,本人深刻体会到 fortran 对于像我这样母语是C 的编程小白的强烈不友好!几天不碰,想要实现一个小小的功能就举步维艰。所以我觉得还是要多总结,今天闲来无事,就对 moudle/subroutine/function 这些用法做一个简单的小结8!
正文
知识点什么的,书上,网上一大堆,所以就不在这里多费笔墨了,这里主要讲一个简单的例子。
1、题目
在这里插入图片描述
题目是一个简单的双线性内插的计算,为了涵盖moudle/subroutine/function 所以本人采用了如下的方法

2、看到题目,我就想创建一个结构体——moudle 的用法

    module typedef
        type point
            real x,y,z
        end type   
    contains
        subroutine set_p(p,x,y,z)
        type(point) p
        real x,y,z
        p.x=x;p.y=y;p.z=z
        end subroutine !Attention here
        subroutine show_p(P)
        type(point) P
        print 100,"  x=",P.x,"  y=",P.y,"  f(x,y)=",P.z
100     format(a4,f9.3,a4,f9.3,a9,f9.3)      
        end subroutine 
    end module

可以看到,创建了一个point 结构体,就相当于C++ 里面的类,里面有x,y,z 三个 real 型的量,其中 z=f(x,y)
然后 contains 了俩子例程

set_p //为结构体赋值
show_p//打印结构体

值得注意的是,
1)在moudle 里面的子例程结束的时候必须用
end subroutine subroutine 是不可以省去的
2)在使用自定义的结构体时,用
type(point) p 有别与C/C#中的 point p

3、函数——function 的用法

function fun(Q1,Q2,x) result(P)
    use typedef
    implicit none
    type(point) Q1,Q2,P
    real x  !x is PQ1/PQ2
    P.z=x*Q2.z+(1-x)*Q1.z
    P.x=x*Q2.x+(1-x)*Q1.x
    P.y=x*Q2.y+(1-x)*Q1.y
    end 

fun 是函数名字,后边()中的是传入形参,result()里面是传出形参
用moudle 的时候,要加use typedef 类似于C 里面的include <...> 你得告诉人家你用的模块的叫什么,不然别人怎么清楚你用的是什么

4、子例程——subroutine 的用法

subroutine sub(Q11,Q12,Q21,Q22,P) 
    use typedef
    implicit none
    type(point) Q11,Q12,Q21,Q22,P,R1,R2,fun  !Attention here
    R1=fun(Q11,Q21,(P.x-Q11.x)/(Q21.x-Q11.x))
    R2=fun(Q12,Q22,(P.x-Q12.x)/(Q22.x-Q12.x))
    P=fun(R1,R2,(P.y-R1.y)/(R2.y-R1.y))
    end subroutine

在这里,可以看到,在使用function 的时候,要对fun 下定义!!!
这里请注意如何调用fun的!
无论是function 还是 subroutine 都要对()里面的参数下定义,参数的类型说明不是放在括号里面,而是现于内部。

老师说subroutine 和 function 并没有本质的区别,但是个人更喜欢subroutine ,因为上机的时候想用function 把我搞炸了(小声bb)

5、完整程序及输出结果

    module typedef
        type point
            real x,y,z
        end type   
    contains
        subroutine set_p(p,x,y,z)
        type(point) p
        real x,y,z
        p.x=x;p.y=y;p.z=z
        end subroutine !Attention here
        subroutine show_p(P)
        type(point) P
        print 100,"  x=",P.x,"  y=",P.y,"  f(x,y)=",P.z
100     format(a4,f9.3,a4,f9.3,a9,f9.3)      
        end subroutine 
    end module
    
    
    program Hello
    use typedef
    implicit none
    type(point) Q11,Q12,Q21,Q22,P  !Attention here
    real x,y
    
    call set_p(Q11,0.0,0.0,0.0)
    call set_p(Q21,1.0,0.0,1.0)
    call set_p(Q12,0.0,1.0,2.0)
    call set_p(Q22,1.0,1.0,3.0)
    p.x=0.3;p.y=0.7
    call sub(Q11,Q12,Q21,Q22,P)
    
    print *,"Q11:"
    call show_p(Q11)
    print *,"Q12:"
    call show_p(Q12)
    print *,"Q21:"
    call show_p(Q21)
    print *,"Q22:"
    call show_p(Q22)
    print *,"P:"
    call show_p(P)
    pause
    end
    
    subroutine sub(Q11,Q12,Q21,Q22,P) 
    use typedef
    implicit none
    type(point) Q11,Q12,Q21,Q22,P,R1,R2,fun  !Attention here
    R1=fun(Q11,Q21,(P.x-Q11.x)/(Q21.x-Q11.x))
    R2=fun(Q12,Q22,(P.x-Q12.x)/(Q22.x-Q12.x))
    P=fun(R1,R2,(P.y-R1.y)/(R2.y-R1.y))
    end subroutine
    
    function fun(Q1,Q2,x) result(P)
    use typedef
    implicit none
    type(point) Q1,Q2,P
    real x  !x is PQ1/PQ2
    P.z=x*Q2.z+(1-x)*Q1.z
    P.x=x*Q2.x+(1-x)*Q1.x
    P.y=x*Q2.y+(1-x)*Q1.y
    end 

这里请注意如何调用sub的!
输出结果

 Q11:
  x=    0.000  y=    0.000  f(x,y)=    0.000
 Q12:
  x=    0.000  y=    1.000  f(x,y)=    2.000
 Q21:
  x=    1.000  y=    0.000  f(x,y)=    1.000
 Q22:
  x=    1.000  y=    1.000  f(x,y)=    3.000
 P:
  x=    0.300  y=    0.700  f(x,y)=    1.700

在这里插入图片描述

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值