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

下载本文档

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

文档简介

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=8.0*(1.0/3.0) 。 (7)数组有一些整体操作的功能;可以方便的对部分元素进行操作 (8)有些情况下可以声明大小待定的数组,很实用的功能4、Fortran 的基本程序结构 先看一看所谓的 &

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

5、 cylinder ! 给主函数起个名字! 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 =

6、3.1415926536 !这是常量的声明方法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 rea

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

8、ght)! and output (area) to the screen.write (*,'(1x,a7,f6.2,5x,a7,f6.2,5x,a5,f6.2)') & !"&" 这里指数运算比 C 方表示续行。还显示了格式化输出'radius=',radius,'height=',height,'area=',areayn = ' 'yn_loop: do! 嵌的另一个 do 循环write(*,*) 'Perform another calculation? yn

9、' read(*,'(a1)') ynif (yn='y' .or. yn='Y') exit yn_loopif (yn='n' .or. yn='N' .or. yn=' ') exit interactive_loop end do yn_loop ! 结束嵌 do 循环end do interactive_loop end program cylinderFortran 程序的主要结构就是这样了。 一般还会有些 module 的部分在主函数前, 函数在主函 数后。三、数据类型及基本输

10、入输出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.0还有指数的形式,如1E10为单精度

11、,1D10为双精度( 3) complex 单精度和双精度complex(kind=4) b( 4) charactercharacter(len=10) c !len为最大长度( 5) logicallogical*2 : d=.ture. ( 等价于 logical(2):d=.ture.)6)自定义类型 type :类似于 C 中的 structFortran 77中给变量赋初值常用DATA命令,可同时给多个变量赋初值 data a,b,string /1, 2.0, 'fortran'/照默认的规定,以 i,j,k,l,m,n需在程序声明与C不同的是,Fortran中变

12、量不声明也能使用,即有默认类型(跟implicit 命 令有关)。按开头的变量被定义为 integer, 其余为 real 。取消该设置部分之前 加 implicit none 。国伦建议一般都使用该语句。 另一点关于声明的不同是 Fortran 有"等价声明 ": integer a,b equivalence(a,b) 使得a,b使用同一块存。这样可以节省存;有时可精简代码。如:equivalence(很 长名字的变量比如三维数组的某个元素,a),之后使用a来编写程序就简洁多了2、基本输入输出输入: read(*,*) a!输出: write(*,*) "te

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

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

15、end if(3)嵌套:if( 逻辑判断式 ) thenif( 逻辑判断式 ) thenif( 逻辑判断式 ) thenelse if(逻辑判断式 ) thenelseend if !没必要跟C语句多时用 了,因为有end ifend ifend if(4) 算术判断: program example implicit none real c write (*,*) "input a number" read (*,*) cif(c) 10,20,30 !10,20和30为行代码,根据c小于/等于/大于0,执行10/20/30 行的程 序10 write (*,*) &qu

16、ot;A"goto 40 !goto 可实现跳到任意前面或后面的行代码处,但用多了破坏 程序结构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 或lo

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

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

19、特色:带署名的循环 可以这样,不易出错:outer: do i=1,3inner: do j=1,3end do inner end do outer还可以这样,很方便:loop 1: do i=1,3loop2: do j=1,3终止整个循环 loop1跳出 loop2 的本次循环,进行 loop2 的if(i=3) exit loop1 !exitif(j=2) cycle loop2 !cycle一次循环 write(*,*) i,j end do loop2 end do loop1还有一些循环主要用于 Fortran 中的数组运算,为 Fortran 特有,很实用六、数组1、数组的声

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

21、方法声明的数组完全相同。与C不同,Fortran索引值默认为从1开始,而且可以在声明时改变该规则: integer a(-3:1) ! 索引值为-3, -2, -1, 0, 1 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,2) 。原则是先放低维的元素,再放高维的元素。此规则称为 column major 3、赋初值(1)最普通的做法:integer a(5)data a /1,2,3,4,5/或 integer : a(5)=(/

22、1,2,3,4,5/)若 integer : 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 i data (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,

23、integer : 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 ! a=(/1,2,3/) ! a=b !所有元素赋值为 5这里假设 a 为一维, a(1)=1,a(2)=2,a(3)=3 对应元素赋值,要求 a,b,c 维数和大小相同,下同a=b+c a=b-c a=b*ca=b/ca=sin(b) !部函数都可

24、以这样用5、操作部分数组元素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) 以及之后的所有元素赋值为 5 a(1:3)=b(4:6) ! 类似于这种的要求左右数组元素个数相同 a(:)=b(:,2) !a(1)=b(1,2),a(2)=b(2,2) ,以此类推6、WHEREwhere 形式上类似于 if ,但只用于设置数组。设有两个同样类型、维数和大小 的数组 a,b 34m where(a<3)b=a !a中小于 3 的元素赋值给 b 对应位置的元素en

25、d where再如: where(a(1:3)/=0) c=a !略去了 end where, 因为只跟了一行 where 可嵌 套,也可类似 do 循环有署名标签7、FORALL有点像 C 中的 for 循环:forall(triplet1,triplet2 ,triplet3,mask)其中 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也可以嵌套

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

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

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

29、值。如果要改变传递参数的值,习惯上用子程序来做 声明方式: real, external : function_name般自定义函数也是放在主程序之后。形式:function function_name(parameter1, parameter2)implicit nonereal: parameter1, parameter2 !声明函数参数类型,这是必需的real:function_name !声明函数返回值类型,这是必需的function_n ame=.! 返回值的表达式 returnend也可以这样直接声明返回值类型,简洁些:real function function_name(p

30、arameter1, parameter2) implicit nonereal: parameter1, parameter2 ! 这个还是必需的function_n ame=.! 返回值表达式 returnend调用: function_name(parameter1,parameter2)不需要 call 命令。 自定义函数可以相互调用。调用时也需要事先声明。 总之,调用自定义函数前需要做声明,调用子程序则不需要3、关于函数中的变量( 1)注意类型的对应。 Fortran 中甚至可以传递数值常量,但只有跟函数定义 的参数类型 对应才会得到想要的结果。如 call ShowReal(1.0

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

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

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

34、n c,d则 a 和 c 共用相同存, b 和 d 共用相同存。全局变量太多时会很麻烦。可以把它们人为归类,只需在定义时在comm o后面加上区间名 。如common /groupe1/ a, common /group2/ b 。这样使用时就不必把所有全局变量 都列出来了,再声明 common /groupe1/ c 就可以用 a、c 全局变量了。可以使用 block data 程序模块。在主程序和函数中不能直接使用前面提到的 data 命令给全局变量赋初值。可以给它们各自赋初值;如果要使用 data 命令必须要这样: block data name implicit none intege

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

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

温馨提示

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

评论

0/150

提交评论