第五章 函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第五章函数
“函数”是自定义函数和子程序的统称。子程序可以用来独立出一段具有特定功能的程序代码,供其它地方调用。自定义函数可以用来扩充出fortran库函数中原来不存在的函数。
5-1 子程序(subroutine)的使用
写程序时,可以把某一段常常被使用、具有特定功能的程序代码独立出来,封装成子程序,以后只要经过调用的call命令就可以执行这一段程序代码。先来看一个使用子程序的实例。
1.program ex0501
2. implicit none
3. call message( ) !调用子程序message
4. call message( ) !再调用一次
5. stop
6.end
7.!子程序message
8.subroutine message( )
9. implicit none
10. write(*,*)"hello"
11. return
12.end
执行结果如下:
hello
hello
程序的第3、4行出现了一个新命令“call”,而call在程序中的意义就如同它的英文原意,是“调用”的意思。所以第3、4行的意思就是“调用一个名字叫做message的子程序”。
子程序和前面所提到的“主程序”(以program开头、end来结束之间的这一段程序代码)最大不同处在于:主程序的程序代码,在程序一开始就自动会被执行,而子程序则不会自动执行,它需要被别人‘调用’才会执行。这就是它之所以被称作“子”的原因。
子程序的程序代码以subroutine开头,它同样要取一个名字,以end或end subroutine 来结束。
一个包含子程序的fortran程序在结构上的模样大致如下:
program main ←----------主程序
……
……←------------------主程序代码
……
end program main ←------主程序结束
subroutine sub1( ) ←----第1个子程序
……
……←------------------子程序代码
……
end subroutine sub1←----第1个子程序结束
subroutine sub2( ) ←----第2个子程序
……
……←------------------子程序代码
……
end subroutine sub2←----第2个子程序结束
主程序并不一定要放在程序代码的最开头,它可以安排在程序中的任意位置,可以先写子程序再写主程序,这都是可以的。
子程序最后一个命令通常是“return”,表示程序要“返回”原来调用它的地方来继续执行程序。如果像主程序一样写成了stop,就会导致子程序执行完后,整个程序就跟着全部结束,这通常不是使用子程序时所想要看到的现象。return命令可以省略。
关于子程序还有一个重要的概念,就是“子程序独立地拥有属于自己的变量声明”。也就是说,在主程序和其它的子程序之间,所声明出来的变量是彼此不相干的,假使在主程序与其他的子程序中使用了同样的变量名称,它们也是彼此没有关系的不同变量。
不过严格来说,不同的程序之间所声明的变量,还是有办法让它们牵扯出关系来。在调用子程序时,可以同时传递一些变量数据过去让它处理,这个操作叫做“传递参数”,来看下面的实例:
1.program ex0502
2.implicit none
3. integer :: a=1
4. integer :: b=2
5. call add(a, b) !把变量a及b交给子程序add来处理
6. stop
7.end
8.
9. subroutine add(first, second)
10. implicit none
11. integer :: first, second !first, second的内容会从call时得到
12. write(*,*) first + second
13. return
14. end
执行后会显示主程序中a + b的结果,也就是3。程序第5行在调用子程序add时,还同时输入了变量a及b。
第9行中first和second是子程序add的两个变量,指定用来接收传递进来的参数。程序第5行进入子程序add后,由于first和second这两个变量是用来接收参数的,first 的初值等于主程序中的a,因为a是调用时所输入的第1个数值。同理second就等于主程序中的b。子程序会计算first + second的值,也就等于是计算主程序中a + b的数值。
了解子程序的使用规则后,现在来写一个比较有用的程序。
例如:在一场田径赛的标枪比赛中,5位选手投掷标枪的情况如下:
1号选手:以30度角,每秒25米的速度掷出标枪。
2号选手:以45度角,每秒20米的速度掷出标枪。
3号选手:以35度角,每秒21米的速度掷出标枪。
4号选手:以50度角,每秒27米的速度掷出标枪。
5号选手:以40度角,每秒22米的速度掷出标枪。
假如忽略空气阻力以及身高等等因素,请写一个程序来计算选手的投射距离。(也就是
计算自由投射运动的抛物线距离)
1.program ex0503
2.implicit none
3. integer, parameter :: players=5
4. real :: angle(players)=(/30.0,4
5.0,35.0,50.0,40.0,/)
5. real :: speed(players)=(/25.0,20.0,21.0,27.0,22.0/)
6. real :: distance(players)
7. integer :: I
8.
9. do I=1,players
10. call get_distance(angle(i),speed(i),distance(i))
11. write(*,"('player',I1,'=',F8.2)") I, distance(i)
12. end do
13.
14. stop
15. end
16.!把0~360的角度转换成0~2 的弧度
17. subroutine angle_to_rad(angle,rad)
18. implicit none
19. real :: angle, rad
20. real, parameter :: pi=3.14159
21.
22. rad=angle*pi/180.0
23.
24. return
25. end
26. !由角度、切线速度来计算投射距离
27. subroutine get_distance(angle, speed, distance)
28. implicit none
29. real :: angle, speed !输入参数
30. real :: distance !准备返回去的结果
31. real :: rad, vx,time !内部使用
32. real, parameter :: G = 9.81
33.
34. call angle_to_rad(angle,rad) !单位转换
35. vx = speed*cos(rad) !水平方向速度
36. time = 2.0*speed*sin(rad)/G !在空中飞行时间
37. distance = vx * time !距离=水平方向速度*飞行时间
38.
39. return
40. end
执行结果如下:
Player 1 = 55.17
Player 2 = 40.77