问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Fortran模块、子程序和函数的使用示例

创作时间:
作者:
@小白创作中心

Fortran模块、子程序和函数的使用示例

引用
CSDN
1.
https://blog.csdn.net/Gou_Hailong/article/details/102468886

作为一个Fortran语言的初学者,我深刻体会到Fortran对于像我这样习惯于C语言的编程小白来说,确实不太友好。几天不碰,想要实现一个小小的功能就感到困难重重。因此,我觉得还是要多总结。今天闲来无事,就对Fortran中的模块(module)、子程序(subroutine)和函数(function)的用法做一个简单的小结。

知识点概述

关于Fortran语言的基础知识,书上和网上都有很多详细的介绍,这里就不多做赘述。本文主要通过一个简单的双线性插值计算的例子,来演示模块、子程序和函数的使用方法。

1. 题目

题目是一个简单的双线性插值计算,为了涵盖模块、子程序和函数的使用,我采用了如下的方法。

2. 创建模块——module的用法

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++中的类,包含三个实型变量xyz,其中z=f(x,y)。模块中包含了两个子程序:

  • set_p:用于为结构体赋值
  • show_p:用于打印结构体

值得注意的是:

  1. 在模块内部的子程序结束时必须使用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()指定。使用模块时需要使用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

这是一个名为sub的子程序,用于计算双线性插值。在使用函数时,需要对函数进行定义。需要注意的是,无论是函数还是子程序,参数的类型说明都需要在括号外部进行。

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 

运行结果如下:

 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

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号