一、总论
直到现今,fortran仍然是土木、水利类工科同学学习计算机语言的首选,除了因为它传统的超强的计算功能,更因为它是最早的计算机高级编程语言,所以广阔的已经成形的计算资源,如各种计算软件等都是由其编译而来,所以,至少在很长一段时间内,fortran仍将活跃在世上,而不会为C/C++、VB等取代。
有必要提一下fortran的基本知识,这些在我们上课的时候可能都没有涉及。
fortran语言规范与编译器的区别:fortran主要的语言规范有fortran77、fortran90以及fortran2003,其中,目前学生学习主要是fortran90规范,因为fortran77实在是太古老了,在其改革到fortran90之后,fortran加入了指针等C/C++中的东西,使得fortran学习、使用起来更为方便,但是这并不是说fortran77就不行了或是怎么的,事实上,众多的使用fortran的研究人员仍然使用着它,譬如说国家地理信息等行业的人员,他甚至可能会对fortran的后续语言规范嗤之以鼻,毕竟这种改变并不能使他的SCI论文增加多少的。值得一提的是,fortran2003语言规范的出台着实让众多学习fortran的童鞋们为之一振,因为它标志着fortran也迈入了面向对象程序设计语言的行列,不过关于它的介绍还不是很多,我在J.Chapmen的fortran95程序设计一书的最后看到了相关介绍,之所以这样,主要是支持fortran2003语言规范的编译器还没有公司开发出来,所以这是一个pity。
其次,再说一下fortran编译器的方面。fortran目前使用的主流编译器为compaq visual fortran系列,intel fortran系列,powerstation ,DVF系列等(我们老师给的应该是DVF5.0),其中,compaq公司被intel收购之后,就生产intel fortran系列了,而powerstation系列属于微软的产品,比较经典的是powerstation4.0,它使得利用windows的内置资源制作友好的图形用户界面以及强大的图形处理能力成为现实。值得一提的是,intel fortran的特色是在配有intel处理器的PC机上可以使得fortran运行能力达到最佳,而且,它是不能直接使用的,需要配上visual studio系列才能安装。由于当前win7系统的普及,所以兼容性也应考虑进编译器的选择方面,intel fortran直到最近的ivf11.x系列才开始解决这个问题,而微软早期的powerstation4.0编译器却莫名其妙的与win7有着良好的兼容性,不过个人不是很喜欢,它的界面比较古董,而且字体形式有限。
其实编译器的影响还是有的,因为它的扩展部分与个人的使用直接相关。
再聊一下工程的概念,其实VB,VC/C++比较注重工程的概念,而fortran,一般情况下,老师只是教导我们创建一个free format file就行了,其实,工程的概念也是比较重要的,特别是如果想实现可视化的话。
● "File" → "New" → "Projects"
项目类型:
a、 Win32 Console Application:
基于命令行的程序(字符界面)。
b 、Standard Graphics Application:
单窗口单任务绘图应用程序,易学易用。
c 、Quick Win Application
多窗口单任务绘图应用程序,易学易用。
d 、Win32 Application
多窗口多任务应用程序,有固定的程序结构,复杂难学。
一般情况下,直接利用Quick Win Application实现可视化,而一般选用的是fortran powerstation4.0编译器。下面将详细介绍。
二、Quick Win Application实现可视化
QuickWin库虽然没有提供Windows的所有应用程序接口功能,但它可以实现以下的多种功能:将控制台应用程序编译为简单的Windows应用程序;像Windows程序一样,最大化或最小化QuickWin程序窗口;调用图形函数;加载和储存位图;选择、复制和粘贴文本、图形;监测和响应鼠标事件;输出图形;改变程序的默认菜单或加入可编程菜单;使用自定义图标;打开多个子窗口等等。任何使用QuickWin的程序均须包含USE MSFLIB语句以访问QuickWin库。若程序中不含有PROGRAM语句,则USE MSFLIB语句应出现在任何声明语句(例如IMPLICIT NONE或INTEGER语句)和其他模块包含语句之前。
下面通过实例,首先介绍了QuickWin程序的特点,然后介绍菜单系统的设计步骤。
QuickWin应用程序的创建过程
可以在Microsoft Fortran PowerStation中调用QuickWin 库来创建QuickWin应用程序。
例:创建显示Nike(耐克)的QuickWin应用程序,这个例子在好多地方都见到过,可能比较经典吧。
其操作步骤如下:
(1) 在Microsoft Developer Studio中单击File菜单下的New菜单项,在New对话框中选择Project Workspace,单击Ok按钮;
(2) 在New Project Workspace对话框中,选择QuickWin Application,将工程名称设置为Nike(存放于C盘中),单击Create按钮;
(3) 再在Microsoft Developer Studio中单击File菜单下的New菜单项,在New对话框中选择Text File,单击Ok按钮,在源程序窗口中编辑好显示Nike的源程序nike.f90(存放于C:\nike目录下)。源程序代码如下 :
PROGRAM NIKE
USEMSFLIB
INTEGER(2) fontnum
INTEGER(4) oldcolor
TYPE(xycoord) XY
OLDCOLOR=setcolorrgb(#00ff00) !设置当前绘图颜色为绿色
FONTNUM=initializefonts() !初始化前景
FONTNUM=setfont('t''Times New Roman''h88w50i') !设置前景字体
call DRAWCURVE(710.,55.,400.,150.,0.6,160.,335.) !画曲线的上半部分
call DRAWCURVE(695.,66.,420.,150.,0.71,160.,365.) !画曲线的下半部分
FONTNUM=floodfillrgb(500,350,#00ff00) !颜色填充
call moveto(int2(370),int2(190),XY) !设置字符的位置
call outgtext("Nike") !输出字符
end
subroutine drawcurve(x,y,lrad,srad,seta,astart,aend)
use msflib
real x,y,lrad,srad,seta,rad,fai,astart,aend !椭圆曲线的有关参数
real tempx,tempy !绘图点的X、Y坐标
integer(2) i,dummy
type(xycoord) xy
rad=sqrt((lrad*COS(astart/100.))**2+(srad*SIN(astart/100.))**2)
fai=atan((srad*SIN(astart/100.))/(lrad*COS(astart/100.)))+3.1415927
tempx=x+rad*COS(fai-seta)
tempy=y+rad*SIN(fai-seta)
call moveto(int(tempx),int(tempy),xy)
do 10 i=int(astart),int(aend)
rad=SQRT((lrad*COS(i/100.))**2+(srad*SIN(i/100.))**2)
fai=ATAN((srad*SIN(i/100.))/(lrad*COS(i/100.)))+3.1415927
tempx=x+rad*COS(fai-seta)
tempy=y+rad*SIN(fai-seta)
dummy=LINETO(tempx,tempy)
10 continue
end subroutine drawcurve
(4) 在Microsoft Developer Studio中单击Insert菜单下的Files into Project菜单项,将nike.f90文件加入到nike工程中;
(5) 在Microsoft Developer Studio中分别单击Build菜单下的Compile、Build、Execute菜单项,用以编译、生成并运行nike文件,得到QuickWin程序的输出结果:
除此而外,fortran还可以程序窗口等,不再一一赘述。
三、fortran结合matlab
matlab是众所周知的比较犀利的应用软件,它有着强大的数值计算,数值模拟,图形处理,电子仿真,和谐的GUI等等优点。但是它也有一个弱点,由于它是解释性语句,所以它是万万不适合执行循环的程序结构的,但是,它自身最大的特点——以矩阵为基本单元(全称matrix lab)可以很好的弥补这一不足。
需要指出的是,matlab最早是由fortran编写的,起初是为了解决复杂繁琐的矩阵运算,很来成为商业软件之后,功能扩展开来,直至今天。所以,fortran与matlab的结合可能达到事半功倍的效果,充分发挥各自的优点,实现win-win.
matlab与fortran的调用方式也是一个头疼的问题,由于matlab仅支持fortran中的双精度类型的数据,所以它们之间的数据的传递存在着一定的问题,而matlab与C语言却有着良好的互相支持的特性,这也是很多matlab教程上只是重点介绍VC与matlab之间的接口问题,而对于fortran则只是一带而过的原因。
其次matlab与fortran的调用方式有编译mex文件、编写matlab引擎等,但大多繁琐复杂,不慎就会出错,本人看了许多之后,觉得有一种比较实用,但是偷工减料的方式——系统调用这个万能的方式挺实用的。下面举了一个实例,是本学期土木工程概论的一个本人写的一个小程序作业:
!本程序应用了系统调用同目录下的matlab文件的过程,所以在执行之前需先
!安装好matlab程序及fortran程序
!说明:编译环境:matlab2010a,compaq visual fortran6.5,windows7操作系统
!编程作者:季昀 0802010133 08级水工一班
program main
implicit none
real*8::a=16,M,q=10,Mt,Mc,Mt1,Mc1
real*8::A1,B,l=48,X,angle
integer::j
!位移法
angle=(10*(24-a)**2/3-5*a**2/4)/(3/a+1/(24-a))
Mt1=5/3.*(24-a)**2+angle*1/(24-a)
Mc1=1.25*a**2+angle*3/a
write(*,*)'当a=16时,最大弯矩','Mtmax=',Mt1,'Mcmax=',Mc1
open(100,file='mt.txt')
open(3,file='mc.txt')
open(4,file='a.txt')
a=24
do
angle=(10*(24-a)**2/3-5*a**2/4)/(3/a+1/(24-a))
Mt=5/3.*(24-a)**2+angle*1/(24-a)
Mc=1.25*a**2+angle*3/a
if(Mt>0)then
write(100,*)Mt
else
write(100,*)abs(Mt)
endif
if(Mc>0)then
write(3,*)Mc
else
write(3,*)abs(Mc)
endif
write(4,*)a
if(abs(Mt)<=.5*abs(Mt1).or.abs(Mc)<=.5*(Mc1))exit
a=a-.001
enddo
write(*,*)'当改变a时,最大弯矩','Mtmax=',abs(Mt),'Mcmax=',abs(Mc)
do while(a>=0)
angle=(10*(24-a)**2/3-5*a**2/4)/(3/a+1/(24-a))
Mt=5/3.*(24-a)**2+angle*1/(24-a)
Mc=1.25*a**2+angle*3/a
if(Mt>0)then
write(100,*)Mt
else
write(100,*)abs(Mt)
endif
if(Mc>0)then
write(3,*)Mc
else
write(3,*)abs(Mc)
endif
write(4,*)a
a=a-.001
enddo
close(100)
close(3)
close(4)
write(*,*)'下面调用matlab作图,请按enter键继续'
read(*,*)
call system('matlab -r st')
write(*,*)'Matlab启动较慢,请等待。。。'
!用系统调用的方式调用
!在同一目录下的matlab文件并执行,做出Mt-a及Mc-a图线
endprogram
另外,调用的matlab程序st.m的代码如下:
clear all;
close all;
clc;
Mt=load('mt.txt');
Mc=load('mc.txt');
a=load('a.txt');
plot(a,Mt,'b',a,Mc,'k');
hold on;
grid on;
xlabel('a');
ylabel('Mt/Mc')
title('Mt/Mc-a?ú??')
legend('Mt','Mc')
编译运行结果如下:
fortran中运行结果:
同时matlab作图:
四、总结
学无止境,这只是冰山一角。。。。。。