Fortran95程序设计【彭国伦著】学习笔记哈尔滨工业大学材料学院黄晓华2009年8月21日一、本文说明本文主要是学习彭国伦《Fortran95程序设计》所做笔记。主要是3~9章(原书共16章),都是昀基本的用法。主要摘录总结了一些Fortran和C语法方面不同的地方,同时还从其它自资料补充了一些相关内容帮助理解。原书思路十分清晰,如果有C语言的基础,应该花一两天就能掌握Fortran基本功能文中蓝色的部分是程序代码关键词,!后面的内容为注释。二、Fortran概述1、名词解释Fortran=FormulaTranslator/Translation,一看就知道有什么特色了:可以把接近数学语言的文本翻译成机械语言。的确,从一开始,IBM设计的时候就是为了方便数值计算和科学数据处理。设计强大的数组操作就是为了实现这一目标。Fortran奠定了高级语言发展的基础。现在Fortran在科研和机械方面应用很广。2、Fortran的主要版本及差别按其发展历史,Fortran编译器的版本其实很多。现在在广泛使用的是Fortran77和Fortran90。Fortran90在Fortran77基础上添加了不少使用的功能,并且改良了77编程的版面格式,所以编程时推荐使用90。鉴于很多现成的程序只有77版本,有必要知道77的一些基本常识,至少保证能够看77程序。以下是77和90的一些格式上的区别。Fortran77:固定格式(fixedformat),程序代码扩展名:.f或.for(1)1~5列可以数字表明语句标号(用作格式化输入出等);7~72列为程序代码编写区;73列可用&作为续行符,往后被忽略;(2)注释符:若某行以C,c,*或者!开头,则说明该行为注释行;(3)续行符:过长行可以续行,除73列&续下行外,可在6列用0以外的任何字符续上行(当然也包括&),习惯使用有顺序便于对上下关系进行记忆的数字;允许19个续行;(4)调试符:固定格式和tab格式中,居于标号区1~5列还可以包含注释符,或调试符。字母D在第一列出现代表调试符。Fortran90:自由格式(freeformat),扩展名:.f90(1)以!引导注释;(2)每行可132字符,行代码放在每行昀前面;(3)以&续行,放在该行末或下行初;允许39个续行。通用格式:代码可以写成所有格式都能使用的形式,需遵循下表规则:空格认为是有意义的语句标号在1~5列注释符只实用!,位置在除了6列外任意列续行符只使用&,位置在开始行73列和以后各续行6列语句7~73列以下都是讨论Fortran90。3、Fortran和C的差异其实两者差异很多,在下面涉及具体方面时可以看到,这里只从Fortran的角度大致提一些。(1)不分大小写;(2)每句末尾不必要写分号;(3)程序代码命令间的空格没有意义;(4)不像C,Fortran程序块中不使用{};(5)数据类型多出了复数和逻辑判断类型。比如复数类型为:COMPLEX::A!声明复数的方法A=(1.0,2.0)!A=1+i复数显然方便了科学计算,满足了工程方面需求。(6)乘幂运算符为(**)。乘幂除了整数还可以是实数形式。如开方,开立方A=4.0**0.5,A=8.0**(1.0/3.0)。(7)数组有一些整体操作的功能,可以方便的对部分元素进行操作;(8)除可指定所有特征的显式数组外,有些情况下可以声明形状、大小待定的假定形状数组、假定大小数组以及迟形数组,方便使用。4、Fortran的基本程序结构先看一看简单HelloFortran程序。PROGRAMMAIN!程序开始,MAIN是PROGRAM的名字,自定义WRITE(*,*)Hello!主程序STOP!终止程序END[PROGRAM[MAIN]]!END用于封装代码,表示代码编写完毕。[]中的内容可省略,下同。再看一段实用的程序,增加感性认识。计算圆柱的表面积,要求输入底面半径和高度,其中展示了Fortran的一些特色用法。PROGRAMCYLINDER!给主函数命名!CalculatetheareaofaCYLINDER.!Declarevariablesandconstants.!Constants=PI=3.1415926536!Variables=RADIUSsquaredandHEIGHTIMPLICITNONE!取消1-N隐含约定INTEGER::IERR!定义整型IERRCHARACTER::YN!定义字符型YNREAL::RADIUS,HEIGHT,AREA!定义实型的RADIUS,HEIGHT,AREAREAL,PARAMETER::PI=3.1415926536!定义PI为常量,值为圆周率INERRACTIVE_LOOP:DO!DO循环,Fortran中的循环可以加标签,如DO前面的INTERACTIVE_LOOP就是标签!PrompttheuserforRADIUSandHEIGHTandreadthem.WRITE(*,*)'EnterRADIUSandHEIGHT.'!屏幕输出提示输入语句READ(*,*,IOSTAT=IERR)RADIUS,HEIGHT!键盘输入。ISOTAT的值用判断输入成功否!IfRADIUSandHEIGHTcouldnotbereadfrominput,thencyclethroughtheloop.IF(IERR/=0)THENWRITE(*,*)'Error,invalidinput.'CYCLEINTERATIVE_LOOP!CYCLE相当于C里的continueENDIF!Computearea.The**meansRaisetoapower.AREA=2*PI*(RADIUS**2+RADIUS*HEIGHT)!指数运算比C方便!Writetheinputvariables(RADIUS,HEIGHT)andoutput(AREA)tothescreen.WRITE(*,'(1X,A7,F6.2,5X,A7,F6.2,5X,A5,F6.2)')&!&表续行;格式化输出'RADIUS=',RADIUS,'HEIGHT=',HEIGHT,'AREA=',AREAYN=''YN_LOOP:DO!内嵌的另一个do循环WRITE(*,*)'Performanothercalculation?y[n]'READ(*,'(AL)')YNIF(YN=='y'.OR.YN=='Y')EXITYN_LOOPIF(YN=='n'.OR.YN=='N'.OR.YN=='')EXITINTERACTIVE_LOOPEDNDOYN_LOOP!结束内嵌do循环ENDDOINTERACTIVE_LOOPEDNPROGRAMCYLINDER以上就是Fortran程序的主要结构。一般还会有些MODULE的部分在主函数前,函数在主函数后。三、数据类型及输入输出1、数据类型,声明及赋初值(1)INTEGER:短整型KIND=2,长整型KIND=4INTEGER([KIND=]2)::A=3!如果声明成INTEGER::A,则默认为长整型。::在声明并同时赋初值时必须要写上;类型名后面有属性说明时也必须保留::;其他情况可略去属性说明。比如声明常数:REAL,PARAMETER::PI=3.1415926!PARAMETER为属性说明(2)REAL:单精度KIND=4(默认),双精度KIND=8REAL([KIND=]8)::A=3.0READ*8A还有指数的形式,如1E10为单精度,1D10为双精度(3)COMPLEX单精度和双精度COMPLEX([KIND=]4)B!使用时B=(X,Y)X为实部,Y为虚部(4)CHARACTERCHARACTER([LEN=]10)C!LEN为字符串昀大长度CHARACTER*10C!也是正确的(5)LOGICALLOGICAL*2::D=.TURE.(等价于LOGICAL(2)::D=.TURE.)(6)自定义类型TYPE:类似于C中的structFortran77中给变量赋初值常用DATA命令,可同时给多个变量赋初值:DATAA,B,STRING/1,2.0,'FORTRAN'/与C不同的是,Fortran中变量不声明也能使用,即有默认类型(跟IMPLICIT命令有关)。按照默认的1-N约定,以I,J,K,L,M,N开头的变量被定义为INTEGER,其余为REAL。取消该设置需在程序声明部分之前IMPLICITNONE,彭国伦建议一般都使用该语句。另一点关于声明的不同是Fortran有等价声明:INTEGERA,BEQUIVALENCE(A,B)使得A,B使用同一块内存。这样可以节省内存;有时可精简代码。如:EQUIVALENCE(很长名字的变量如三维数组的某个元素,A),之后使用A来编写程序就简洁多了。2、输入输出语句(1)输出语句有PRINT语句和WRITE语句:PRINTf,输出项列表WRITE(u,f)输出项列表!对于字符,Fortran77用''。Fortan90中一般和''都可。另外:○1f是格式说明符,指明了输出所用的格式。它有三种形式:a.*:表控输出,整型占11列,实型占15列,数据间隔一个空格;b.描述字符常量:如PRINT'(1X,2F7.3)',X,Y。常用的描述符如下表所示。类型描述符一般格式举例说明IrIw[.d]WRITE(*,(I5,I3,I5.4))100,100000,3OUTPUT:__100***_0003整型B,O,Zr()w分别为二进制、八进制、十六进制,用法类似I小数型FrFw.dWRITE(*,(F5.2,F4.1,F3.0))1.5,-1.05,1.05OUTPUT:_1.50-1.1***指数型ErEw.dWRITE(*,(E15.7))123.45OUTPUT:__0.12345600E+03实型普通型GrGw.d综合了F和E,可根据实际大小输出逻辑型LrLw真输出T,假输出F;输入可以是.TRUE.和.FALSE.和以F/T开头的字符串可重复编辑(对输入输出进行编辑)字符型ArA[w]WRITE(*,(A6,A3))HELLO,HELLOOUTPUT:_HELLOHELr重复数,1时可省,w字段宽度;整型中d为至少输出位,不足补0,实型中d为小数占位数;–号小数点均占一位;输出大于设定均为*号X输出空格nXWRITE(*,(I3,3X))20080819OUTPUT:200___19第一行为1X可做纵向走纸符/WRITE(*,(I3,I4/I1,I2//))I,J,M,N输出第一行为I,J值,第二行为M,N值,第三空行换行符,n个/可以输出n-1个空行非重复编辑(直接传递信息)\WRITE(*,(INPUT:,\))READ(*,*)VALUE则提示后不换行取消回车换行c.格式说明(FORMAT)语句标号n。FORMAT专用于输入输出,一般格式:nFORMAT(格式说明)!n为语句标号,必需;格式说明无引号○2u是设备号,用于知名具体设备,可以是无符号常量或者整型表达式或者*号。○3输出项可为常量、变量、函数以及表达式,还可为隐含的DO循环。如DOI=10,5,-1WRITE(*,*)IENDDO!输出1098765(2)输入语句READf,输入项列表READ(u,f)输入项列表!注意逗号,说明和输出语句相同四、流程控制1、运算符(1)关系运算符==/===!Fortran90用法.EQ..NE..GT..GE..LT..LE.!Fortran77用法(2)逻辑运算符.AND..OR..NOT..EQV..NEQV.!.AND.两边的式子成立,整个条件成立;!.OR.两边的式子只要有一个成立,整个条件就成立!仅.NOT.可连接一个表达式,其余左右两边都要有表达式(可以是LOGICAL类型的变量);如果后面的式子不成立,整个式子就算成立;!.EQV.:当两边逻辑运算值相同时为真;!.NEQV.:当两边逻辑运算值不同时为真。2、IF(1)基本使用方法IF(逻辑