Fortran的主要版本差别_第1页
Fortran的主要版本差别_第2页
Fortran的主要版本差别_第3页
Fortran的主要版本差别_第4页
Fortran的主要版本差别_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、、 Fortran 的主要版本及差别按其发展历史, Fortran 编译器的版本其实很多。 现在在广泛使用的是Fortran 77和 Fortr an90。Fortran 90 在 Fortran 77 基础上添加了不少使用的功能,并且改良了 77 编程的版面格式,所以编程时推荐使用90。鉴于很多现成的程序只有77 版本,有必要知道 77 的一些基本常识,至少保证能够看懂 77 程序。以下是77 和 90 的一些格式上的区别。Fortran 77 : 固定格式( fixed format ),程序代码扩展名: .f 或 .for( 1)若某行以 C,c 或*开头,则该行被当成注释;( 2)每行

2、前六个字符不能写程序代码,可空着,或者15 字符以数字表明行代码(用作格式化输入输出等); 772为程序代码编写区; 73往后被忽略;( 3)太长的话可以续行,所续行的第六个字符必须是"0" 以外的任何字符。Fortran 90 :自由格式( free format ), 扩展名: .f90( 1)以 "!" 引导注释;( 2)每行可 132 字符,行代码放在每行最前面;( 3)以&续行,放在该行末或下行初。以下都是讨论Fortran 90 。3、 Fortran 的一些特点,和C 的一些不同其实很多,在下面涉及具体方面时可以看到。这里只是大致提

3、一些。( 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 的基本程序结构先看一

4、看所谓的 "Hello Fortran" 程序。program main ! 程序开始, main 是 program 的名字,完全自定义write(*,*) "Hello" ! 主程序stop!终止程序end programmain !end 用于封装代码,表示代码编写完毕。 中的内容可省略,下同。再看一段实用一些的程序, 好有点感性认识。 程序用于计算圆柱的表面积, 要求输入底面半径和高。其中展示了 Fortran 的一些特色用法。程序摘自维基。其实是一个叫的网上引用的维基的网页。推荐去看看! 能查到不少有意思的东西。program cylinder

5、 ! 给主函数起个名字! Calculate the area of a cylinder.! Declare variables and constants.! constants=pi! variables=radius squared and heightimplicit none ! Require all variables to be explicitly declared这个一般都是要写上的。下面会进一步说明。integer : ierrcharacter : ynreal : radius, height, areareal, parameter : pi = 3.141592

6、6536 !这是常量的声明方法interactive_loop:do !do 循环, Fortran 中的循环可以加标签,如 d面的 interactive_loop 就是标Prompt the user for radius and height and read them.write (*,*) 'Enter radius and height. read (*,*,iostat=ierr) radius,height屏幕输出键盘输入。 isotat 的值用于判断!输入成功否。If radius and height could not be read from input, th

7、en cycle through the loop.if (ierr /= 0) thenwrite(*,*) 'Error, invalid input.'cycle interactive_loop !cycleend if相当于C里的continue! Compute area. The * means "raise to a power."area = 2 * pi * (radius*2 + radius*height) !便! Write the input variables (radius, height)! and output (area

8、) to the screen.write (*,'(1x,a7,f6.2,5x,a7,f6.2,5x,a5,f6.2)') & !"&"这里指数运算比C方表示续行。还显示了格式化输出radius=',radius,'height=',height,'area=',areado 循环yn = ' ' yn_loop: dowrite(*,*) 'Perform another calculation? yn'read(*,'(a1)') ynif (yn=

9、'y' .or. yn='Y') exit yn_loopif (yn='n' .or. yn='N' .or. yn=' ') exit interactive_loopend do yn_loop结束内嵌 do 循环end do interactive_loop end program cylinderFortran 程序的主要结构就是这样了。 一般还会有些module 的部分在主函数前,函数在主函数后。三、数据类型及基本输入输出1、数据类型,声明及赋初值1) integer : 短整型 kind=2, 长整型

10、 kind=4integer(kind=2) : a=3如果声明成integer: a ,则默认为长整型。!":" 在声明并同时赋初值时必须要写上; 类型名后面有形容词时也必须有; 其 他情况可略去! 所谓形容词,可以看一下这个。比如声明常数real , parameter : pi=3.1415926。 parameter 就是形容词。( 2) real :单精度 kind=4 (默认),双精度kind=8real(kind=8) : a=3.0还有指数的形式,如1E10为单精度,1D10为双精度( 3) complex 单精度和双精度 complex(kind=4) b

11、( 4) charactercharacter(len=10) c !len 为最大长度( 5) logicallogical*2 : d=.ture. (等价于 logical(2):d=.ture.)( 6)自定义类型type :类似于 C 中的 structFortran 77中给变量赋初值常用DATAOr令,可同时给多个变量赋初值data a,b,string /1, 2.0, 'fortran'/与 C 不同的是, Fortran 中变量不声明也能使用 , 即有默认类型(跟 implicit 命令有关)。按照默认的规定,以 i,j,k,l,m,n 开头的变量被定义为

12、integer, 其余为 real 。取消该设置需在程序声明部分之前加 implicit none 。彭国伦建议一般都使用该语句。另一点关于声明的不同是Fortran 有"等价声明" :integer a,bequivalence(a,b)使得 a,b 使用同一块内存。这样可以节省内存;有时可精简代码。如:equivalence( 很长名字的变量 比如三维数组的某个元素,a) ,之后使用 a 来编写程序就简洁多了。2、基本输入输出输入:read(*,*) a输出:write(*,*) "text"print 后面的 *表示按从键盘读入在屏幕上输出。 Fo

13、rtran 77 用' text' 。 Fortran 90!一般 " " 和 ' ' 都可print *, "text" ! 只能屏幕输出( *,* )完整写为( unit=*,fmt=* )。其中 unit 为输入 / 输出位置,如屏幕,文件等; fmt 为格式。如果这两项都写成* ,则按默认的方式进行,即上面描述的。默认格式输四、流程控制1、运算符( 1)逻辑运算符= /= > >= < <= !Fortran 90用法.EQ. .NE. .GT. .GE. .LT. .LE. !Fortra

14、n 77用法( 2)涉及相互关系的集合运算符.AND. .OR. .NOT. .EQV. .NEQV.!仅.NOT.连接一个表达式,其余左右两边都要有表达式(可以是 logical类型的变量)!.EQV. :当两边逻辑运算值相同时为真, .NEQV. :当两边逻辑运算值不同时为2、 IF(1) 基本 :if( 逻辑判断式) thenend if如果 then 后面只有一句,可写为if(逻辑判断式) !then 和end if可省略(2) 多重判断:if( 逻辑判断式) then else if else if else end if(3) 嵌套:if( 逻辑判断式) thenif( 逻辑判断式

15、) thenif( 逻辑判断式) thenelse if( 逻辑判断式) thenelseend if !没必要跟C语句多时用 了,因为有end ifend ifend if(4) 算术判断:program exampleimplicit nonereal cwrite (*,*) "input a number" read (*,*) cif(c) 10,20,30 !10,20和30为行代码,根据c小于/等于/大于0,执行10/20/30 行的程序10 write (*,*) "A"goto 40 !goto 可实现跳到任意前面或后面的行代码处,但用

16、多了破坏程序结构20 write (*,*) "B"goto 4030 write (*,*) "C"goto 4040 stopend3、 SELECT CASE类似于 C 的 switch 语句select case( 变量 )case (数值1) ! 比如 case(1:5) 代表1<=变量 <=5会执行该模块 !case (1, 3, 5)代表变量等于1或3或5会执行该模块 case (数值2) !括号中数值只能是integer,character 或logical 型常量,不台匕 能是 real 型 case defaultend

17、case4、 PAUSE, CONTINUEpause暂停程序执行,按 enter可继续执行continue 貌似没什么用处,可用作封装程序的标志五、循环1、 DOdo counter= 初值 , 终值 , 增/ 减量!counter 的值从初值到终值按增 / 减量变化, !counter每取一个值对应着一次循环。增/减量不写则默认为 1!循环主体也没有必要用end doFortran 77 中不是用 end do 来终止,而是下面这样子:do 循环最后一行的行代码counter= 初值 , 终值 , 增/ 减量行代码 !这是do的最后一行2、 DO WHILEdo while( 逻辑运算 )

18、end do类似于C中的while(逻辑运算)。一开始那个计算圆柱表面积的程序中, 应该也算是这一类。 不过它是通过内部的if 语句来控制循环。 看来也是可以的, 不过在这本书上没看到这样写。 其实应该也可以归于下面这种。3、没看到和C里面的dowhile(逻辑运算);相对应的循环语句,不过可以这样,保证至少做一次循环:do while(.ture.) if( 逻辑运算)exit !exit 就好比C里面的break °C里的continue在Fortran 里是 cy cle end do4、 Fortran 的一个特色:带署名的循环可以这样,不易出错:outer: do i=1,

19、3inner: do j=1,3end do innerend do outer还可以这样,很方便:loop 1: do i=1,3loop2: do j=1,3终止整个循环loop1if(i=3) exit loop1 !exitif(j=2) cycle loop2 !cycle跳出 loop2 的本次循环,进行loop2 的一次循环write(*,*) i,jend do loop2end do loop1还有一些循环主要用于 Fortran 中的数组运算,为 Fortran 特有,很实用。六、数组1、数组的声明和 C 不同的是, Fortran 中的数组元素的索引值写在()内,且高维的

20、也只用一个(),如下integer a(5) ! 声明一个整型一维数组real : b(3,6) ! 声明一个实型二维数组类型可以是integer, real, character, logical或 type 。最高可以到 7 维。数组大小必须为常数。但是和C语言不同,Fortran也有办法使用大小可变的数 组,方法如下:integer, allocatable : a(:) !声明大小可变经过某个途径得知所需数组大小 size 之后,用下面的语句:allocate(a(size) ! 配置内存空间之后该数组和通过一般方法声明的数组完全相同。1 开始,而且可以在声明时改变该规则:-2, -1

21、 , 0, 1为可使用的元素与 C 不同, Fortran 索引值默认为从integer a(-3:1) ! 索引值为 -3 ,integer b(2:3,-1:3) !b(23,-13)2、数组在内存中的存放和 C 不同, Fortran 中的数组比如 a(2,2) 在内存中存放顺序为 a(1,1),a(2,1),a(1,2),a(2,2column major 。) 。原则是 先放低维的元素,再放高维的元素。此规则称为3、赋初值( 1)最普通的做法:integer a(5)data a /1,2,3,4,5/或 integer : a(5)=(/1,2,3,4,5/)若 integer :

22、 a(5)=5 ,则 5 个元素均为 5对于 integer : a(2,2)=(/1,2,3,4/)根据数组元素在内存中存放的方式,等价于赋值a(1,1)=1,a(2,1)=2,a(1,2)=3,a(2,2)=4( 2)利用 Fortran 的特色:隐含式循环。看例子就明白了。integer a(5)integer idata (a(i),i=2,4)/2,3,4/ !(a(i),i=2,4)认值 1看例子就明白了。表示 i 从 2 到 4 循环, 增量为默还可以这样:integer i五个元素分别赋值为 1, 2, 2, 2, 5五个元素分别赋值为 1, 2, 3, 4,integer :

23、 a(5)=(/1,(2,i=2,4),5/)integer : b(5)=(/i, i=1,5/)!5还可以嵌套data (a(i,j),i=1,2),j=1,2)=/1,2,3,4/ !a(1,1)=1,1(2,1)=2,a(1,2)=3,a(2,2)=44、操作整个数组设 a, b 为相同类型、维数和大小的数组a=5! 所有元素赋值为 5a=(/1,2,3/) ! 这里假设 a 为一维, a(1)=1,a(2)=2,a(3)=3a=b对应元素赋值,要求a,b,c 维数和大小相同,下同a=b+c a=b-c a=b*c a=b/c a=sin(b) ! 内部函数都可以这样用5、操作部分数组

24、元素a 为一维数组a(3:5)=(/3,4,5/) !a(3)=3,a(4)=4,a(5)=5a(1:5:2)=3!a(1)=3,a(3)=3,a(5)=3a(3:)=5!a(3) 以及之后的所有元素赋值为 5a(1:3)=b(4:6)! 类似于这种的要求左右数组元素个数相同a(:)=b(:,2)!a(1)=b(1,2),a(2)=b(2,2) ,以此类推6、 WHEREwhere 形式上类似于 if ,但只用于设置数组。设有两个同样类型、维数和大小的数组 a,b34m where(a<3)b=a !a 中小于 3 的元素赋值给b 对应位置的元素end where再如: where(a(

25、1:3)/=0) c=a ! 略去了 end where, 因为只跟了一行where 可嵌套,也可类似do循环有署名标签7、 FORALL有点像 C 中的 for 循环:,mask)forall(triplet1,triplet2 ,triplet3其中 triplet 形如 i=2 : 6: 2,表示循环,最后一个数字省略则增量为 1例如:forall(i=1:5,j=1:5,a(i,j)<10)a(i,j)=1end forall又如: forall(i=1:5,j=1:5,a(i,j)/=0) a(i,j)=1/a(i,j)forall 也可以嵌套使用,好比 C 中 for 循环的

26、嵌套。七、函数Fortran 中函数分两类:子程序( subroutine )和自定义函数( function )。自定义函数本质上就是数学上的函数, 一般要传递自变量给自定义函数, 返回函数值。 子程序不一定是这样,可以没有返C 是一样的。1、子程序目的:把某一段经常使用的有特定功能的程序独立出来,可以方便调用。习惯上一般都把子程序放在主程序结束之后。形式:subroutine name (parameter1, parameter2)! 给子程序起一个有意义的名字。可以传递参数,这样可以有返回值。括号内也可以空着,代表不传递参数。implicit noneinteger: paramete

27、r1, parameter2 ! 需要定义一下接收参数的类型。!接下来的程序编写跟主程序没有任何差别。mreturn !跟C不同,这里表示子程序执行后回到调用它的地方继续执行下面的 程序。不一定! 放在最后。可以放在子程序的其他位置,作用相同;子程序中 return之后的部分不再执行。end subroutine name调用:使用 call 命令直接使用,不需要声明。在调用处写:call subroutine name(parameter1,parameter2)、,、-、 t _'注意点:a. 子程序之间也可相互调用。直接调用就是了,像在主程序中调用子程序一样。b. 传递参数的原理

28、和C 中不同。Fortran 里是传址调用 (call byaddress/reference),就是传递时用的参数和子程序中接收时用的参数使用同一个地址, 尽管命名可以不同。 这样如果子程序的执行改变子程序中接收参数的值,所传递的参数也相应发生变化。c.子程序各自内部定义的变量具有独立性,类似于C。各自的行代码也具有独立性。因此各个子程序 和主程序中有相同的变量名、行代码号,并不会相互影响。2、自定义函数和子程序的明显不同在于: 需要在主程序中声明之后才能使用。 调用方式也有差别。另外按照惯例调用函数不去改变自变量的值。 如果要改变传递参数的值, 习惯上用子程序来做。声明方式: real,

29、external : function_name一般自定义函数也是放在主程序之后。形式:function function_name(parameter1, parameter2)implicit nonereal: parameter1, parameter2 ! 声明函数参数类型,这是必需的real:function_name !声明函数返回值类型,这是必需的function_name=.!返回值的表达式returnend也可以这样直接声明返回值类型,简洁些:real function function_name(parameter1, parameter2) implicit none这

30、个还是必需的real: parameter1, parameter2 return endfunction_name=返回值表达式调用: function_name(parameter1,parameter2)不需要 call 命令。自定义函数可以相互调用。调用时也需要事先声明。总之,调用自定义函数前需要做声明,调用子程序则不需要。3、关于函数中的变量( 1)注意类型的对应。 Fortran 中甚至可以传递数值常量,但只有跟函数定义的参数类型对应才会得到想要的结果。如 call ShowReal(1.0) 就必须用 1.0 而不是 1。(2)传递数组参数,也跟 C 一样是传地址,不过不一定是数

31、组首地址,而可以 是数组某个指定元素的地址。 比如有数组 a(5) , 调用 call function(a) 则传递 a(1) 的地址, 调用 call functio n(a(3) 则传递 a(3) 的地址。( 3)多维数组作为函数参数,跟C 相反的是,最后一维的大小可以不写,其他维大小必须写。这决定于 Fortran 中数组元素 column major 的存放方式。( 4)在函数中,如果数组是接收用的参数,则在声明时可以用变量赋值它的大小,甚至可以不指定大小。例如:subroutine Array(num,size)implicit noneinteger: sizeinteger n

32、um(size) ! 可以定义一个数组, 其大小是通过传递过来的参数决定的。这个很实用returnend( 5) save 命令:将函数中的变量值在调用之后保留下来,下次调用此函数时该变量的值就是上次保留的值。只要在定义时加上save 就行:integer, save : a=1( 6)传递函数(包括自定义函数、库函数、子程序都是可以的)。类似于C 中的函数指针。需要在主程序和调用函数的函数中都声明作为参数传递的函数。如real, external : function ! 自定义函数 real, intrinsic : sin !库函数external sub !子程序( 7)函数使用接口(

33、 interface ):一段程序模块。以下情况必需:a. 函数返回值为数组b. 指定参数位置来传递参数时c. 所调用的函数参数个数不固定d. 输入指标参数时e. 函数返回值为指针时。具体用法结合例子容易看懂。例子都很长。看书吧。4、全局变量功能就不用说了。 原理: 根据声明时的相对位置关系而取用, 不同与 C 中根据变 量名使用。如果在主程序中定义:integer : a,bcommon a,b ! 就是这样定义全局变量的在子程序或自定义函数中定义:integer : c,dcommon c,d则 a 和 c 共用相同内存, b 和 d 共用相同内存。全局变量太多时会很麻烦。可以把它们人为归

34、类,只需在定义时在common面加上区间名。如common /groupe1/ a, common /group2/ b 。这样使用时就不必把所有全局变量都列出来了,冉声明 common /groupel/ c 就可以用 a、c全局变量了。可以使用 block data 程序模块。在主程序和函数中不能直接使用前面提到的data 命令给全局变量赋初值。可以给它们各自赋初值;如果要使用 data 命令必须要这样:block data nameimplicit noneinteger a,b,creal d,ecommon a b ccommon /group1/ d,edata a,b,c,d,e

35、 /1,2,3,4.0,5.0/end block data name5、 ModuleModule不是函数。它用于封装程序模块,一般是把具有相关功能的函数及变量 封装在一起。用法很简单, 但能提供很多方便, 使程序变得简洁, 比如使用全局变量不必每次都声明一长串,写在Module里调用就行了。Module 一般写在主程序开始之前形式:module module_name end module module_name使用: 在主程序或函数中使用时, 需要在声明之前先写上一行: use module_name37m。Module 中有函数时必须在 contains 命令之后(即在某一行写上 co

36、ntains 然后下面开始写函数, 多所有函数都写在这个contains 之后) 。 并且 module 中定义过的变量在module 里的函数中可以直接使用,函数之间也可以直接相互调用,连module 中的自定义函数在被调用时也不用先声明的。6、 include 放在需要的任何地方,插入另外的文件(必须在同一目录下) 。如:include 'funcion.f90'八、文件1、文本文件Fortran 里有两种读取文件的方式,对应于两种文件顺序读取:用于文本文件直接读取:用于二进制文件这里只摘录关于文本文件的读取。一般模式如下。character(len=20):filenamein="in.txt", filenameout="out.txt" !文件名logical ali

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论