为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > Part I Fortran语言基础

Part I Fortran语言基础

2010-10-25 50页 doc 1MB 24阅读

用户头像

is_112290

暂无简介

举报
Part I Fortran语言基础数值分析程序设计 数值分析程序设计 Part I Fortran语言基础 COMPAQ VISUAL FORTRAN 6.5 0​ 编译器的使用 0.1 编译器简介 高级语言以及汇编语言的程序代码在没有转换成机器代码前,计算机是无法执行的。编译器的功能是将高级语言的程序代码翻译成计算机可执行的机器码,也就是生成扩展名为EXE, COM的文件。 0.2 Visual Fortran的使用 Visual Fortran起源于Microsoft的Fortran PowerStation 4.0,这套工具后来卖给Digital公司继续...
Part I Fortran语言基础
数值程序 数值分析程序设计 Part I Fortran语言基础 COMPAQ VISUAL FORTRAN 6.5 0​ 编译器的使用 0.1 编译器简介 高级语言以及汇编语言的程序代码在没有转换成机器代码前,计算机是无法执行的。编译器的功能是将高级语言的程序代码翻译成计算机可执行的机器码,也就是生成扩展名为EXE, COM的文件。 0.2 Visual Fortran的使用 Visual Fortran起源于Microsoft的Fortran PowerStation 4.0,这套工具后来卖给Digital公司继续开发,第二个版本称为Digital Visual Fortran 5.0,Digital被Compaq并购之后,接下来的版本6.0和6.5称为Compaq Visual Fortran。下面的介绍以Compaq Visual Fortran 6.5作范例。 Visual Fortran被组合在一个叫做Microsoft Visual Studio的图形接口开发环境中。Visual Studio提供一个统一的使用接口,这个接口包括文字编辑功能、Project管理功能、调试工具等。而编译器则被组合到Visual Studio中,VF和VC++使用相同的使用接口。 Visual Fortran 6.5除了完全支持Fortran 95的语法外,扩展功能方面提供了完整的Windows程序开发工具,专业版还含有IMSL数值计算连接库。另外还可以和VC++直接互相连接使用,也就是把Fortran和C语言的程序代码混合编译成一个执行文件。 安装好Compaq Visual Fortran后,运行Developer Studio就可以开始编译Fortran程序了。 运行Developer Studio启动Visual Fortran,默认程序名称为Compaq Visual Fortran 6.5 选择File菜单中的New选项 在弹出的对话框中,选择Project标签。在Project中选择Fortran Console Application。 在Project Name的文本框中给定Project的名字,Location会显示出整个Project的工作目录。点击”OK”。 选择An empty project选项,单击Finish按钮。 这个画面只有在VF6.5中才会出现,他显示Project打开后自动生成的文件,直接单击OK按钮。 这是刚设置完成的Project后的界面,目前还没有任何程序代码。 以上是建立Project的方法。Visual Studio的环境是以Projiect作为编译单位,*.dsp或*.dsw是Project文件。打开Project后,还要把程序代码加入Project中才能编译。下面是添加程序代码文件的方法。 再次选择File菜单中的New选项。 在对话框中,选择Files标签,选择Fortran Free Format Source File。并为文件命名。 编写一个程序或打开一个已有的程序。 选择Build菜单中的Execute选项,VF会编译并执行编译好的程序。 程序执行的结果。 最后再一次简单地说明编译程序的过程: (1)​ 建立一个新的Project(File/New,选择Project选项卡,选择Fortran Console Program,给定Project名称)。Project会保存成*.dsw文件。 (2)​ 生成一个新的程序文件(File/New,选择Files选项卡,选择Fortran Free Format Source File,给定文件名),或是插入一个已有的程序文件(选项Project/Add to Project/Files)。程序代码会保存成*.f90或*.for文件。 (3)​ 用Build菜单中的Execute选项来编译并运行程序,或只是单击Build选项来只作编译,不运行程序。 (4)​ 要写新的程序可以另外建立一个新的Project,或是直接更换Project中的文件。千万不要把两个独立的程序文件放在同一个Project中,否则导致编译过程出现错误。 (5)​ 下次修改程序时,可以直接使用File/Open Workspace来打开*.dsw的Project工程文件。 作业: 1、熟悉Fortran编译器的使用方法。 1​ Fortran语言基本概念 1.0 程序书写格式 Fortran程序代码的编写格式有两种:Free Format(自由格式)和Fixed Format(固定格式)。 固定格式属于旧式写法,他在编写版面上有很多限制。自有格式是Fortran90之后的新写法,取消了许多旧的限制。Fortran程序代码扩展名为*.F或*.FOR的文件是以Fixed Format编写的程序;以*.F90为扩展名的文件,是以Free Format编写的程序。今后我们编写的程序建议采用自由格式编写。 1.0.1​ Fixed Format(固定格式) 在固定格式中,规定了程序代码每一行中每个字段的意义。第7~72个字符是可以用来编写程序的字段。每一行的前5个字符只能是空格或者是数字,数字用来作为“行代码”。每一行的第6个字符只能是空格或者“0”以外的字符。 第1个字符:如果是字母C,c或者星号*,这一行文本会被当作说明批注,不会被编译。 第1~5个字符:如果是数字,就是用来给这一行程序代码取个代号。不然只能是空格。 第6个字符:如果是“0”以外的任何字符,表示这一行程序会接续上一行; 第7~72个字符:Fortran程序代码的编写区域。 第73个字符之后:不使用,超过的部分会被忽略,有的编译器会发出错误信息。 C FIXED FORMAT DEMO program main write(*,*) 'Hello' write(*,*) 1'Hello' 100 write(*,*) 'Hello' 10 stop end 注意:程序中的空格,没有任何意义。固定格式是配合早期使用穿孔卡片输入程序所发明的格式。熟悉固定格式,有助于阅读早期的Fortran程序代码。 1.0.2​ Free Format(自由格式) 自由格式基本上允许非常自由地编写格式,他没有规定每一行的第几个字符有什么作用。需要注意的事项只有以下几点: (1)​ 叹号“!”后面的文本都是注释; (2)​ 每一行可以编写132个字符; (3)​ 行号放在每行程序的最前面; (4)​ 一行程序代码的最后如果是符号“&”,代表下一行程序会和这一行连接。如果一行程序代码的开头是符号&,代表它会和上一行程序连接。 看一个自由格式编写的程序: ! Free Format program main write(*,*) "Hello" ! 这也是注解 write(*,*) & "Hello" wr& &ite(*,*) "Hello" end 1.1 字符集 字符集是指编写Fortran程序时,所能使用的所有字符及符号。Fortran所能使用的字符集有: 英文字母:A~Z及a~z(英文字母不区分大小写); 数字:0~9; 22个特殊符号: := + - * / . ‘ ! “ % & ; < > ? $ _(还有一个显示不出来的空格符) 注意:Fortran是不区分大小写的语言。所以,INTEGER, Integer, inteGER是相同的命令。 1.2 数据类型 整数(INTEGER):整数又可以分为长整型与短整型。在个人计算机中长整型占用32 bits(4 bytes)的空间,长整型可以保存的数值范围在-2147483648~+2147483647(也就是-231+1~231)之间;短整型占用16 bits (2 bytes)的空间,保存数值的范围在-32768~+32767之间。 浮点数(REAL):浮点数有两种类型:单精度和双精度。 单精度浮点数占用32 bits的空间,有效位数为6~7位。可记录的最大数值为 ,最小数值为 。 双精度浮点数占用64 bits,有效位数为15~16位。可记录的最大数值为 ,最小数值为 。 复数(COMPLEX):单精度和双精度。以 表示的复数,其中a,b是由两个浮点数来记录的。 字符型(CHARACTER):计算机除了记录数之外,可以记录一段文本或称作字符串。记录一个字符需要一个字节。 逻辑型(LOGICAL):只有两种结果:真(TRUE)和假(FELSE)。在二进制中,通常以1代表真,0代表假。 使用Fortran编写程序,必须事先数据类型。不同数据类型必须经过转换才能互通。 1.3 数学表达式 Fortran使用的数学运算符号,根据运算优先级顺序排列如下: + 加法 - 减法 * 乘法 / 除法 ** 乘幂(乘方) ( ) 括号 越是下面的运算符号,运算的优先级越高。 Fortran的数学表达式和手写的差别主要有三点: (1)​ 乘幂要连用两个星号**, 例如 必须写成4**3; (2)​ 乘号不能省略,2a应当写作2*a; (3)​ 除法算式 应当写作((a+b)*(c+d))/(2*(e+f)); 1.4 变量命名 在Fortran中,变量命名要注意一些原则: (1)​ 变量的名称以使用英文字母为主,可以含有下划线或数字,但前缀必须是英文字母; (2)​ 变量名的长度最多31个字符; (3)​ 变量名不要与Fortran的命令名相同,也不要与程序名相同; (4)​ 程序中变量名不区分大小写。 1.5 Fortran程序结构 程序开始 PROGRAM MAIN ………………… 主程序代码 WRITE(*,*) “Hello” ………………… 程序结束 STOP 主程序代码结束 END 例如: program main write(*,*) "Hello" stop end program main 作业: 1、​ 变量命名有哪些要求? 2、​ 变量的类型有哪些? 2​  输入输出及声明 ​  WRITE命令 语法:WRITE(UNIT, FMT) 注释:屏幕输出。UNIT输出位置 FMT输出格式。默认格式WRITE(*,*)。默认输出格式unit=6,也就是屏幕输出。 program main write(*,*) "Hello" stop end program main 其他的输出格式参考Fortran的帮助。 ​  PRINT命令 program main print *,"Hello" stop end program main Print的用法和write大致相同,只是print后面不适用括号,而且只有一个星号。这个星号的意义是不限定输出格式。 ​  声明 所谓声明是指:在程序代码中,程序员向编译器要求预留一些存放数据的内存空间。看一个例子: program ex0404 integer a a=3 write(*,*) "a=",a stop end integer a声明变量为整型。编写程序时,应当根据变量的类型选择适当的数据类型,数据类型选用不当,可能造成错误。这种错误有时是编译器无法察觉的。 2.3.1 整数类型(INTEGER) 语法:integer(kind=n) a 注释:kind的值决定整型数据类型。kind=2短整型,kind=4长整型。默认为长整型。 Integer a A=1.5 最终的结果为a=1,这是因为a为整型,会把小数部分无条件舍去。 2.3.2 浮点数(REAL) 语法:real(kind=n) a 注释:kind的值决定浮点数的精度类型。kind=4单精度浮点数(有效数字位数6~7位),kind=8双精度浮点数(有效数字位数15位)。默认为单精度浮点数。 超大数值的设置: 单精度浮点数:1.23E20 双精度浮点数:1.232365D10 计算机在进行浮点数计算时,需要对位,由于有效数位的限制,可能造成大数吃小数的情况。 2.3.3 复数(COMPLEX) 语法:complex(kind=n) a a=(x,y) 注释:kind的值决定浮点数的精度类型。kind=4单精度浮点数(有效数字位数6~7位),kind=8双精度浮点数(有效数字位数15位)。默认为单精度浮点数。 2.3.4 字符及字符串(CHARACTER) 语法:character(len=n) a 注释:len决定字符串的长度。字符串赋值由双引号定义 a=”I am a student!” program ex0413 character(len=20) string string = "Good morning." write(*,*) string string(6:) = "evening." ! 重设设定从第6个字符之后的字符串 write(*,*) string end 执行结果: Good morning. Good evening. 注意:Fortran的命令不区分大小写,但是在字符串中是区分大小写的。 关于字符串的有关函数,请查阅相关的帮助。 2.2.5 逻辑变量(LOGICAL) 语法:logical a 注释:逻辑变量的值为“true”和“false”。逻辑变量输出值为”T”和”F” a=.true. a=.false. 逻辑变量用于程序的逻辑判断语句,一般并不输出。 ​  READ命令 语法:read(*,*) a program ex0417 integer a read(*,*) a ! 由键盘读入一个整数 write(*,*) a ! 写出读进变量a的内容 end Read命令用于实时接受用户从键盘输入数据。Read命令配合输入格式可以方便读取文件中的数据。有关格式命令参考帮助文件。 ​  格式化输入(FORMAT)命令 2.5.1 格式化输出概论 Format命令用来设置输出格式,看一个例子: program ex0420 integer a a=100 write(*,100) a ! 使用行代码100地方设定的格式来输出变数a 100 format(I4) ! 最前面的100是行代码, 把这一行程序代码给一个编号 end 程序的执行结果使用4个字符宽输出整数,前面没有多余的空格。 Format命令中可以使用很多的格式控制描述。下面列出所有格式命令的功能([]中的选项可以省略): Aw——以w个字符宽来输出字符串; BN——定义文本框中的空位为没有东西,在输入时才需要使用; BZ——定义文本框中的空位为0,在输入时才需要使用; Dw.d——以w个字符宽输出指数类型的浮点数,小数部分占用d个字符宽; EW.d[Ee]——以w个字符宽输出指数类型的浮点数,小数部分占用d个字符宽,指数部分占用e个字符; Enw.d[Ee]——以指数类型输出浮点数; Esw.d[Ee]——以指数类型输出浮点数; Fw.d——以w个字符宽输出浮点数,小数部分占用d个字符宽; Gw.d[Ee]——以w个字符宽输出任何种类的数据; Iw[.m]——以w个字符宽输出整数,最少输出m个数字; Lw——以w个字符宽输出T或F的真假值; nX——把输出的位置向右跳过n个位置; /——代表换行; :——在没有更多数据时结束输出; 下面看一个例子: program ex0421 integer a real b complex c logical d character(len=20) e a=10 b=12.34 c=(1,2) d=.true. e="FORTRAN" write(*,"(1X,I5)") a ! 用I来格式化整数 write(*,"(1X,F5.2)" ) b ! 用F来格式化浮点数 write(*,"(1X,F4.1,F4.1)" ) c ! complex也是浮点数 write(*,"(1X,L3)") d ! 用L来输出logical write(*,"(1X,A10)") e ! 用A来输出字符串 end 上例将输出格式写在Write命令内,下面的例子采用Format命令规定输出格式: PROGRAM ex0422 INTEGER A REAL B COMPLEX C LOGICAL D CHARACTER*(20) E A=10 B=12.34 C=(1,2) D=.true. E="FORTRAN" WRITE(*,100) A ! 用I来格式化整数 WRITE(*,200) B ! 用F来格式化浮点数 WRITE(*,300) C ! complex也是浮点数 WRITE(*,400) D ! 用L来输出logical WRITE(*,500) E ! 用A来输出字符串 100 FORMAT(1X,I5) 200 FORMAT(1X,F5.2) 300 FORMAT(1X,F4.1,F4.1) 400 FORMAT(1X,L3) 500 FORMAT(1X,A10) END 详细的输出格式使用方法,参考相关帮助。 2.5.2 详论格式化输出 格式化输出的控制字符非常丰富,但是常用的并不多,所以不需要记住每一个控制字符。一般来说,“I、F、E、A、X”是最常用的几个格式,最好能记住他们的用法。 【Iw[.m]】——以w个字符的宽度输出整数[至少输出m个数字] write(*,”(I5)”) 100 100 !采用5个字符宽输出,100前补两个空白 write(*,”(I3)”) 10000 *** !设置的输出文本框不足,输出3个*以示警告 write(*,”(I5.3)”) 10 010 !强迫输出 ​  声明的其他命令 2.6.1 IMPLICT命令 Fortran编译器会根据变量名的首字母自动决定变量类型,以I、J、K、L、M、N开头的变量被视为整型变量。 implicit none关闭默认类型功能,所有变量都要事先声明; implicit real(M-P) implicit integer(A,B,C) 2.6.2 常数的声明方法(PARAMETER) 程序中的一些不变量,可以声明为常数,其在程序中是不变的。看一个例子: program ex0429 implicit none real pi parameter(pi=3.14159) write(*,"(F4.2)") sin(pi/6) end 2.6.3 设置变量初值 程序中的变量可以在声明变量类型时同时赋值。 program ex0430 integer :: a = 1 real :: b = 2 complex :: c = (1,2) character(len=20) :: str = "FORTRAN 90" write(*,*) a,b,c,str end 在Fortran77中,需要使用Data命令设值初值。 2.6.4 等价声明(EQUIVALENCE) 把两个以上的变量,声明他们使用同一个内存地址,就是等价声明。使用等价声明可以节省内存、精简程序代码。 integer a, b equivalence(a,b) !声明a,b这两个变量使用同一块内存空间 注意:所有的声明都应当放在程序代码的可执行描述之前。 ​  混合运算 混合运算是指:在算式中所进行计算的数字类型不同。进行混合运算时,要先经过数据类型的转换,以免出现错误。 program ex0432 implicit none integer :: a=1 integer :: b=2 real :: c c=real(a)/real(b) ! 经由库函数real把整数转换成浮点数 write(*,"(F5.2)") c end 程序的执行结果:0.5 如果不做类型转换,c=a/b=0,出现错误的结果。 ​  自定义数据类型 利用自定义数据类型可以定义数据结构体,管理不同类型的数据,这对于数据库建立是非常有用的。 program ex0434 implicit none ! 开始建立person这个类型 type :: person character(len=30) :: name ! 人名 integer :: age ! 年龄 integer :: height ! 身高 integer :: weight ! 体重 character(len=80) :: address ! 地址 end type person type(person) :: a ! 声明一个person类型的变量 write(*,*) "NAME:" read(*,*) a%name write(*,*) "AGE:" read(*,*) a%age write(*,*) "HEIGHT:" read(*,*) a%height write(*,*) "WEIGHT:" read(*,*) a%weight write(*,*) "ADDRESS:" read(*,"(A80)") a%address write(*,100) a%name,a%age,a%height,a%weight 100 format("Name:",A10/,"Age:",I3/,"Height:",I3/,"Weight:",I3,& &"Addres:",A50) stop end 每个类型为person的变量中,都有name, age, height, weight, address这几个元素可以使用,使用时要加上一个百分号%来取用他们。Person%age, person%weight。 Fortran90 中的type功能与C语言中的struct类似。 3​ 流程控制与逻辑运算 3.1 IF语句 ​ IF语句基本用法 IF语句基本流程: IF (逻辑表达式) THEN 程序代码 END IF program ex0501 implicit none real(kind=4) :: speed write(*,*) "speed:" read(*,*) speed if ( speed > 100.0 ) then ! speed > 100 时才会执行下面这一行程序 write(*,*) "Slow down." end if stop end IF命令可以与ELSE搭配,逻辑流程为: IF (逻辑表达式) THEN 程序代码 ELSE 程序代码 END IF program ex0502 implicit none real(kind=4) :: height ! 记录身高 real(kind=4) :: weight ! 记录体重 write(*,*) "height:" read(*,*) height ! 读入身高 write(*,*) "weight:" read(*,*) weight ! 读入体重 if ( weight > height-100 ) then ! 如果体重大于身高减去100, 会执行下面的程序 write(*,*) "Too fat!" else ! 如果体重不大于身高减去100, 会执行下面的程序 write(*,*) "Under control." end if stop end 3.1.2 逻辑运算 Fortran90的逻辑判断运算符号:(括号内为Fortran77的逻辑判断缩写符号) == 相等 (.EQ.) /= 不相等 (.NE.) > 大于 (.GT.) >= 大于等于 (.GE.) < 小于 (.LT.) <= 小于等于 (.LE.) 逻辑关系运算浮号: .AND. 逻辑与 .OR. 逻辑或 .NOT. 逻辑非 .EQV. 两边表达式运算结果相同时,结果为真 .NEQV. 两边表达式运算结果不同时,结果为真 注意:逻辑判断运算优先级高于逻辑关系运算。应此下面的两种逻辑关系式时等价的: a>=80 .and. a<90 (a>=80) .and. (a<90) 不过为明显逻辑运算关系,建议使用后一种写法。 3.1.3 多重判断IF-ELSE IF 多重判断流程: if (条件1)then 程序代码 else if (条件2) then 程序代码 else if (条件3)then 程序代码 else if (条件4)then 程序代码 else 程序代码 end if 利用多重判断编写成绩等级查询程序: program ex0505 implicit none integer score character grade write(*,*) "Score:" read(*,*) score if ( score>=90 .and. score<=100 ) then grade='A' else if ( score>=80 .and. score<90 ) then grade='B' else if ( score>=70 .and. score<80 ) then grade='C' else if ( score>=60 .and. score<70 ) then grade='D' else if ( score>=0 .and. score<60 ) then grade='E' else ! score<0 或 score>100的不合理情形 grade='?' end if write(*,"('Grade:',A1)") grade stop end 3.1.4 嵌套IF语句 IF (……) THEN IF (……) THEN IF (……) THEN ELSE IF (……) THEN ELSE END IF END IF END IF 例 判断平面上一个点位于第几象限。 program ex0508 implicit none real x,y integer ans write(*,*) "Input (x,y)" read(*,*) x,y if ( x>0 ) then if ( y>0 ) then ! x>0,y>0 ans=1 else if ( y<0 ) then ! x>0, y<0 ans=4 else ! x>0, y=0 ans=0 end if else if ( x<0 ) then if ( y>0 ) then ! x<0, y>0 ans=2 else if ( y<0 ) then ! x<0, y<0 ans=3 else ! x<0, y=0 ans=0 end if else ! x=0, y=任意数 ans=0 end if if ( ans/=0 ) then ! ans不为0时, 代表有解 write(*,"('第',I1,'象限')") ans else write(*,*) "落在轴上" end if stop end 3.2 浮点数及字符的逻辑运算 3.2.1 浮点数的逻辑判断 使用浮点数作逻辑运算,要避免使用“等于”判断。因为使用浮点数作计算时,有效位数有限,难免出现计算上的误差,理想的等号不一定会成立。 program ex0509 implicit none real :: a real :: b = 3.0 a=SQRT(b)**2-b ! 理论上a应该要等于0 if ( a==0.0 ) then write(*,*) "a等于0" else write(*,*) "a不等于0" end if stop end 浮点数在作逻辑判断时,应当预留一定的误差空间。 3.2.2 字符的逻辑判断 除了数字可以比较大小外,字符也可以比较大小。字符比较大小的根据是比较他们的ASCII码。 3.3 SELECT CASE语句 多重判断可以采用SELCET CASE语句。其逻辑流程为: select case (变量) case (数值1) 程序代码 case (数值2) 程序代码 case (数值n) 程序代码 case default 程序代码 end select 例 判断成绩等级 program ex0512 implicit none integer score character grade write(*,*) "Score:" read(*,*) score select case(score) case(90:100) ! 90到100分之间 grade='A' case(80:89) ! 80到89分之间 grade='B' case(70:79) ! 70到79分之间 grade='C' case(60:69) ! 60到69分之间 grade='D' case(0:59) ! 0到59分之间 grade='E' case default ! 其它情形 grade='?' end select write(*,"('Grade:',A1)") grade stop end 注意:使用SELECT CASE有以下限制: (1)​ 只能使用整数、字符和逻辑变量,不能使用浮点数及复数; (2)​ 每个CASE中所使用的数值必须是固定值,不能使用变量; 3.4 其他流程控制 3.4.1 GOTO命令 GOTO命令功能强大,可以任意跳转程序的执行顺序。正因为这样,一般不建议使用,以免造成程序逻辑混乱。 3.4.2 PAUSE、CONTINUE、STOP命令 PAUSE 程序执行到PAUSE时,会暂停执行,直到用户按下ENTER键,才会恢复执行; CONTINUE 没有实际功能,只是为方便程序阅读; STOP 结束程序; 4​ 循环语句 4.1 DO循环 语法: do counter=a, b , c 程序代码 end do 注释: do循环标志 counter计数器 a计数初值 b计数终值 c计数增量,默认为1,可以省略 end do结束循环 例 利用循环计算2+4+6+8+10 program ex0602 implicit none integer, parameter :: limit=10 ! 计数器的上限 integer counter ! 计数器 integer :: ans = 0 ! 拿来累加使用 do counter=2, limit ,2 ans = ans + counter end do write(*,*) ans stop end 注释:DO循环可以多层嵌套 do i=1,10 do j=1,10 do k=1,10 {程 序 代 码} end do end do end do DO循环有明确的循环次数,在已知需要循环的次数时使用。若事先无法知道循环的次数,采用下面的循环方式。 4.2 DO WHILE循环 语法: do while (逻辑表达式) 循环体 end do 例 利用循环计算2+4+6+8+10 program ex0604 implicit none integer, parameter :: limit=10 ! 计数器的上限 integer counter ! 计数器 integer :: ans = 0 ! 拿来累加使用 counter = 2 ! 设定计数器初值 do while( counter <= limit ) ans = ans + counter counter = counter + 2 ! 计数器累加 end do write(*,*) ans stop end 例 猜体重 program ex0605 implicit none real, parameter :: weight=45.0 real, parameter :: e = 0.001 real :: guess = 0.0 do while( abs(guess-weight) > e ) write(*,*) "Weight:" read(*,*) guess end do write(*,*) "You're right" stop end Do While循环使用时应当注意正确设置循环判断表达式,以免进入死循环。 4.3 循环的流程控制 4.3.1 CYCLE命令 CYCLE命令可以略过循环的程序模块中,在CYCLE命令后面的所有程序代码,直接跳回循环的开头来进行下一次循环。 例 假设某大楼共有9层,但电梯在4层不停,试写一个程序仿真大楼电梯从一层到九层的信号显示情况。 program ex0606 implicit none integer :: dest = 9 integer floor do floor=1, dest if ( floor==4 ) cycle write(*,*) floor end do stop end 4.3.2 EXIT命令 EXIT的功能是直接跳出当前循环。 例 猜体重 program ex0607 implicit none real, parameter :: weight=45.0 real, parameter :: error=0.0001 real :: guess = 0.0 do while( .true. ) !循环条件永远成立 write(*,*) "weight:" read(*,*) guess if ( abs(guess-weight)students ) exit write(*,*) student(i) end do stop end 执行后会要求按照学生学号一个一个地输入成绩,输入完成后就可以按照学生学号来查询成绩,输入一个不存在的学号会结束程序。 5.1.2 二维数组 声明数组大小时,时用两个数字,他就声明为二维数组。 integer a(10,5) real a(12,3) 二维数组经常被用来当成矩阵使用。 例 二阶矩阵加法 program ex0704 implicit none integer, parameter :: row = 2 integer, parameter :: col = 2 integer :: matrixA(row,col) integer :: matrixB(row,col) integer :: matrixC(row,col) integer r ! 用来指定row integer c ! 用来指定column ! 读入矩阵A的内容 write(*,*) "Matrix A" do r=1, row do c=1, col write(*,"('A(',I1,',',I1,')=')") r,c read(*,*) matrixA(r,c) end do end do ! 读入矩阵B的内容 write(*,*) "Matrix B" do r=1, row do c=1, col write(*,"('B(',I1,',',I1,')=')") r,c read(*,*) matrixB(r,c) end do end do ! 把矩阵A,B相加并输出结果 write(*,*) "Matrix A+B=" do r=1, row do c=1, col matrixC(r,c) = matrixB(r,c)+matrixA(r,c) ! 矩阵相加 write(*,"('(',I1,',',I1,')=',I3)") r,c,matrixC(r,c) end do end do stop end 这个程序使用了三个两层循环,前两个循环用来读入矩阵,最后的一个循环用来作矩阵的加法,同时输出相加的结果。 5.1.3 多维数组 Fortran最多可以声明高达七维数组。 Integer a(d1,d2,…,dn) 数组除了可以使用基本的4种类型外,还可以使用自定义类型,这部分将在下面一章介绍。 5.1.4 另类的数组声明 在没有特别赋值的情况下,数组的索引值都是从1开始的。可以经过特别声明的方法改变这个默认值。 Integer a(0:5) Integer a(-3,3) 不过建议不要使用,以免在数组引用过程中,由于不同数组的索引值声明不同,造成混乱。 5.2 数组内容的设置 数组中的每一个元素,可以在程序执行中逐一进行赋值,也可以在声明时给定初值。 5.2.1 赋初值 数组可以象变量一样使用DATA来设置数组的初值。 Integer A(5) DATA A /1,2,3,4,5/ DATA中的数据区中可以用“*”表示数据重复 Integer a(5) Data a /5*3/ ! 5*3是指5个3 隐含式循环赋初值方法 INTEGER A(5) INTEGER I DATA (A(I), I=2,4)/2,3,4/ !I从2增加到4,初值设定结果为A(2)=2, A(3)=3, A(4)=4, A(1)和A(5)没有设值初值。 可以省略DATA INTEGER :: A(5)=(/I, I=1,5/) !A=[1,2,3,4,5], 注意括号和除号间不能有空格。 直接赋初值法: INTEGER :: A(5)=(/1,2,3,4,8/) !给定的数据应与数组数据个数相同,否则将出现错误。 5.2.2 对整个数组的操作 Fortran90在Fortran77的基础上增加了许多新功能,大大简化了程序编写的复杂度,原来必须循环才能做到的事情,现在一个命令即可。 举例说明如下: 【a=5】将数组a的每一个分量值设为5; 【a=(/1,2,3/)】等号右边的数字数目必须和数组维数相同; 【a=b】a(i)=b(i) 【a=b+c】a(i)=b(i)+c(i) 【a=b-c】 【a=b*c】a(i,j)=b(i,j)*c(i,j),不是真正的矩阵乘法 【a=b/c】a(k,j)=b(k,j)/c(k,j) 【a=sin(b)】a(k)=sin(b(k)) 【a=b>c】a,b,c为同维数组。a为逻辑型数组 5.2.3 部分数组的操作 A(3:5)=5 数组的3-5分量设置为5 A(3:)=5 数组第三个分量之后的分量设置为5 A(3:5)=(/1,2,3/) 数组的3-5分量设置为1,2,3 A(1:3)=B(4:6) 将数组B的第4-6分量值赋值给数组A的第1-3分量 A(1:5:2)=3 数组的第1 3 5分量设置为3 A(1:10)=A(10:1:-1) 数组翻转 A(:)=B(:,2) 数组B第二行赋值给数组A A(:,:)=B(:,:,3) 数组B第三维赋值给数组A 5.2.4 WHERE命令 WHERE命令可以根据逻辑判断来使用数组中的一部分元素。 program ex0711 implicit none integer :: i integer :: a(5)=(/ (i,i=1,5) /) integer :: b(5)=0 where( a<3 ) b = a elsewhere b = 2 end where write(*,"(5(I3,1X))") b stop end 这里程序将数组a中数值小于3的元素找出来,并把这些元素的值设置给数组b同样位置的元素,其他元素设置为2。程序执行结果得到数组b为: 1 2 2 2 2 5.2.5 FORALL命令 语法:forall(triple, mask) end forall triple是一个三元组,省略第三个默认值为1,如I=1:10:2。Mask是用来作条件判断的,跟where命令中使用的条件判断类似。看一个例子:这个程序声明一个二维数组作为矩阵使用。使用forall命令把矩阵的上半部分设置为1,对角线设置为2,下半部分设置为3。 program ex0714 implicit none integer I,J integer, parameter :: size = 5 integer :: a(size,size) forall ( I=1:size, J=1:size, I>J ) a(I,J)=1 ! 上半部分 forall ( I=1:size, J=1:size, I==J ) a(I,J)=2 ! 对角线部分 forall ( I=1:size, J=1:size, I a(j) ) then ! a(i)跟a(j)交换 t=a(i) a(i)=a(j) a(j)=t end if end do end do write(*,"(10I4)") a stop end 例 矩阵乘法 program ex0719 implicit none integer, parameter :: L=3, M=4, N=2 real :: A(L,M) = (/ 1,2,3,4,5,6,7,8,9,10,11,12 /) real :: B(M,N) = (/ 1,2,3,4,5,6,7,8 /) real :: C(L,N) integer :: i,j,k do i=1,L do j=1,N C(i,j) = 0.0 do k=1,M C(i,j) = C(i,j)+A(i,k)*B(k,j) end do end do end do do i=1,L write(*,*) C(i,:) end do stop end 6​  7​ 函数(FUNCTION) 在程序代码中,经常会在不同的地方需要重复某一个功能和重复使用某一段程序,这个时候就可以使用函数。函数是自定义函数和子程序的统称。 6.1 子程序(SUBROTINE) 写程序时,可以把某一段常被使用的具有特定功能的程序代码独立出来,封装成子程序,以后只要经过调用CALL命令就可以执行这一段程序代码。看一个实例: program ex0801 implicit none call message() ! 调用子程序message call message() stop end ! 子程序message subroutine message() implicit none write(*,*) "Hello." return end 程序执行结果: Hello. Hello. 子程序和主程序(以program开始,end来结束的程序代码)的最大不同在于:主程序的程序代码,在程序一开始就自动被执行,而子程序则不会自动执行,它需要被别人调用才会执行。 子程序的程序代码以Subroutine开头,同样需要取一个名字,以end或end subroutine结束。子程序的名字比主程序的名字重要的多,它是识别子程序的标志。 一个包含子程序的Fortran程序在结构上的模样大致如下: program mian !主程序 {程序代码} end program main !主程序结束 subroutine sub1() !第一个子程序 {程序代码} end subroutine sub1 !第一个子程序结束 subroutine sub2() !第二个子程序 {程序代码} end subroutine sub2 !第二个子程序结束 主程序并不一定放在程序代码的开头,它可以安排在程序中的任意位置,可以先写子程序再写主程序。 子程序可以在程序的任何地方被别人调用,甚至可以自己调用自己,这个操作称为“递归”。子程序的详细使用方法请参考FORTRAN的帮助文件。 关于子程序还有一个重要的
/
本文档为【Part I Fortran语言基础】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索