1.子程序(subrountine)的使用
把常常用于使用、具有特定功能的程序代码独立出来,封装程子程序,以后调用使用call即可。
program chapter4_exercise !主程序
implicit none
call sub1()
call sub2()
pause
end program chapter4_exercise
subroutine sub1() !子程序sub1
implicit none
write(*,*)"This is sub1"
call sub2()
return
end subroutine sub1
subroutine sub2() !子程序sub2
implicit none
write(*,*)"This is sub2"
return
end subroutine sub2
例:假设在一场田径赛的标枪选项中,有5位选手的投掷标枪的情况为:
1号选手:以30度角,每秒25米的速度掷出标枪。
2号选手:以45度角,每秒20米的速度掷出标枪。
3号选手:以35度角,每秒21米的速度掷出标枪。
4号选手:以50度角,每秒27米的速度掷出标枪。
5号选手:以40度角,每秒22米的速度掷出标枪。
假设忽略空气阻力以及身高等因素,请写出一个程序来计算选手们的投射距离(即计算自由投射运动的抛物线距离)
!法一:
program chapter4_exercise
implicit none
integer,parameter::players=5
real::angle(players)=(/30.0,45.0,35.0,50.0,40.0/)
real::speed(players)=(/25.0,20.0,21.0,27.0,22.0/)
real::distance(players)
integer::i
do i=1,players
call Get_Distance(angle(i),speed(i),distance(i))
write(*,"('Player',I1,'=',F8.2)")i,distance(i)
end do
pause
end program chapter4_exercise
!把0-360的角度转换程0-2pi的弧度
subroutine Angle_To_Rad(angle,rad)
implicit none
real angle,rad
real,parameter::pi=3.14159
rad=angle*pi/180.0
return
end
!由角度、切线速度来计算投射距离
subroutine Get_Distance(angle,speed,distance)
implicit none
real angle,speed !输入的参数
real distance !准备返回去的结果
real rad,Vx,time !内部使用
real,parameter::G=9.81
call Angle_To_Rad(angle,rad) !单位转换
Vx=speed*cos(rad) !水平方向速度
time=2.0*speed*sin(rad)/G !在空中飞行时间
distance=Vx*time !距离=水平方向速度*飞行时间
return
end
!法二:自定义函数
program chapter4_exercise
implicit none
integer,parameter::players=5
real::angle(players)=(/30.0,45.0,35.0,50.0,40.0/)
real::speed(players)=(/25.0,20.0,21.0,27.0,22.0/)
real::distance(players)
real,external::Get_Distance !声明Get_Distance是一个函数
integer::i
do i=1,players
distance(i)=Get_Distance(angle(i),speed(i))
write(*,"('Player',I1,'=',F8.2)")i,distance(i)
end do
pause
end program chapter4_exercise
!把0-360的角度转换成0-2pi的弧度
real function Angle_To_Rad(angle)
implicit none
real angle
real,parameter::pi=3.14159
Angle_To_Rad=angle*pi/180.0
return
end
!由角度、切线速度来计算投射距离
real function Get_Distance(angle,speed)
implicit none
real angle,speed !输入的参数
real rad,Vx,time !内部使用
real,external::Angle_To_Rad !声明Angle_To_Rad是个函数
real,parameter::G=9.81
rad=Angle_To_Rad(angle) !单位转换
Vx=speed*cos(rad) !水平方向速度
time=2.0*speed*sin(rad)/G !在空中飞行时间
Get_Distance=Vx*time !距离=水平方向速度*飞行时间
return
end
2.全局变量(COMMON)
2.1 COMMON的使用
Common是Fortran77中使用“全局变量”的方法,它用来定义一块共享的内存空间。
取用全局变量时,是根据它们声明时的相对位置关系来作对应,而不是使用变量名称来对应。
program chapter4_exercise
implicit none
integer::a,b
common a,b !定义a,b是全局变量中的第1、2个变量
a=1
b=2
call ShowCommon()
pause
end program chapter4_exercise
subroutine ShowCommon()
implicit none
integer::num1,num2
common num1,num2 !定义num1,num2是全局变量中的第1、2个变量
write(*,*)num1,num2
return
end
由于全局变量使用“地址对应”的方法在程序中共享数据,使用在程序设计时常常会有麻烦出现,如:在主函数中使用了6个变量当全域变量,子程序只使用第6个全域变量,它仍然要宣告前5个变量在前面垫着,才能拿到第6个变量来使用。
为解决这一麻烦,将变量归类、放在彼此独立的COMMON区间中。
program chapter4_exercise
implicit none
integer::a,b
common /group1/ a
common /group2/ b
a=1
b=2
call ShowGroup1()
call ShowGroup2()
pause
end program chapter4_exercise
subroutine ShowGroup1()
implicit none
integer::num1
common /group1/ num1
write(*,*)num1
return
end
subroutine ShowGroup2()
implicit none
integer::num1
common /group2/ num1
write(*,*)num1
return
end
2.2 BLOCK DATA
COMMON变量不能直接在子程序或主程序中使用DATA来设置初值,要在BLOCK DATA命令来设置初值。
BLOCK DATA只能用作设置全局变量的初值,故只能包含跟声明有关的描述,程序命令不能放在这个程序模块中。
全局变量不能声明为常量,所以BLOCK DATA中不能出现PARAMETER。
program chapter4_exercise
implicit none
integer::a,b
common a,b !a,b放在不署名的全局变量空间中
integer::c,d
common /group1/ c,d !c,d放在group1的全局变量空间中
integer::e,f
common /group2/ e,f !e,f放在group2的全局变量空间中
write(*,"(6I4)")a,b,c,d,e,f
pause
end program chapter4_exercise
block data
implicit none
integer a,b
common a,b !a,b放在不署名的全局变量空间中
data a,b /1,2/ !设置a,b的初值
integer c,d
common /group1/ c,d !c,d放在group1的全局变量空间中
data c,d /3,4/ !设置c,d的初值
integer e,f
common /group2/ e,f !e,f放在group2的全局变量空间中
data e,f /5,6/ !设置e,f的初值
end block data
2.3 注意事项
COMMON只是用来提供一块共享的内存,编译器不会帮忙做类型的检查。
在使用COMMON时要注意:(1)变量的类型;(2)变量的位置
如果在主程序声明为浮点数,而在子程序中声明为整型则会出现错误。
program chapter4_exercise
implicit none
real a
common a !把浮点数a放在全局变量中
a=1.0
call ShowCommon()
pause
end program chapter4_exercise
subroutine ShowCommon()
implicit none
integer a
common a !把整数a放在全局变量中
write(*,*)a
return
end
试着通过bitview.exe来发现结果。