吐槽:作为一个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