- 目录:
【注释】
【并行】
【续行】
【程序开始】
【常量】◆整型◆实型◆复型◆逻辑型◆字符◆例子◆其他进制
【变量】
【变量声明】◆类型说明&种别说明◆属性说明◆例子◆赋初值
【数组】◆三元下标◆向量下标◆数组赋值◆数组运算◆WHERE构造◆FORALL构造◆函数名称◆动态数组
【派生类型】
【算术运算】
【关系运算】
【逻辑运算】
【判断IF构造】
【GOTO循环】
【DO循环】◆隐DO循环◆无循环变量◆跳出循环◆DO WHILE
【多重选择CASE构造】
【READ,WRITE 输入输出】◆文件◆WRITE语句◆READ◆I/O列表◆OPEN◆CLOSE◆定位语句◆内部文件
【FORMAT语句】
【一些说明】
【一些建议】
- 【注释】
整行注释,第一个字母为 C 或者 *
附加注释,与句后面用 !
!--------------------------------------------------------
! 说明(F90)
!--------------------------------------------------------
- 【并行】
!--------------------------------------------------------
a=1.0 ; b=2.0
!--------------------------------------------------------
- 【续行】
F90中一行为132列,允许有39个续行。在语句行最后加上续行符“&”号。如果字符串被打断,跨2行以上,则在续行的开始位置也要加&号。
第6列上写一个非空格和非零的字符(任何ASCII字符), 常用C
- 【程序开始】
!--------------------------------------------------------
PROGRAM main
END PROGRAM main
!--------------------------------------------------------
- 【常量】
◆整型 (默认4字节)
100_1 !单字节整型常量
2000
2000_4 !4字节整型常量
◆实型 (默认4字节)
print *, 3.14159265358979_8 ! 直接打印双精度数
print *, 3.14159265358979_4 ! 直接打印单精度数(7位有效数字)
◆复型 (默认2×4字节)
(a,b)=(实数,实数)
◆逻辑型 (默认4字节) .TRUE. 和 .FALSE.
a=.TRUE.
◆字符型 (F90用"")
name="char"
例:"I'm a boy." (长为10字节)
'I''m a boy.' (长为10字节)
字符子串:
A(3:11) -> 'CDE12345F',
A(I+4:9) -> 'E1234'(I=1),'1234'(I=2)
A(:5) -> 'ABCDE'
A(11:) -> 'FGH'
A(:) -> 'ABCDE12345FGH'
A(3:3) -> 'C'
A=A(:5)//A(6:) !字符串的合并运算
求字符串长度的函数:LEN(字符串)
不计尾部空格的字符串长度函数:LEN_TRIM(字符串)
求子串在父串位置的函数:INDEX
验证字符串的函数:VERIFY
除去尾部空格函数:TRIM
比较字符大小的函数:LGE、LGT、LLE、LLT
◆例如:
21_2+7.6_4 表示整型种别为2的数21与实型种别为4的数7.6相加。
3.8E-5_4
0.87D-16 禁止说明种别值
(4.7_8,5) 复数表示用括号,逗号分开前面的实部(种别值为8的实数)和后面的虚部(缺省种别值的整数)。
.FALSE._4 表示逻辑型,其常数值是假,种别值是4。
1_'计算数学'
1_'αβγ' 字符串的字符不只限于Fortran字符集内,处理系统支持的图形符号也是允许的。
◆整数的其他进制:
在F90中,还可以根据需要定义二进制、八进制和十六进制正整数常量。二进制常量的表示方法是以字母B开头,后跟定界符括起来的数字串,定界符可以是撇号或括号,数字是0或1,如:B'01011',B(01011)。八进制常量的表示方法是以字母O开头,后跟定界符括起来的数字串,数字范围是0至7,如:O'10472'。十六进制常量的表示方法是以字母Z开头,后跟定界符括起来的数字或字母串,数字范围是0至9,字母范围为A至F,如:Z'18E2D'。但要注意,整数的这些形式,仅限于出现在DATA赋值语句中。
- 【变量】
变量可用字符: 字母A-Y,数字0-9,下划线_ (最多31个字符)
数组 a(4)
- 【变量声明】
F90程序中的数据都有三个特征:类型、种别、属性
类型说明[(种别说明)][,属性说明表] :: 变量名表[=初值]
例如:Real (KIND=4), DIMENSION(4) :: array !同:Dimension array(4)
◆类型说明 & 种别说明
整型说明语句
INTEGER([KIND=]1) 或 INTEGER*1 -128—127
INTEGER([KIND=]2) 或 INTEGER*2 -32768—32767
INTEGER([KIND=]4) 或 INTEGER*4 -2147483648—2147483647 缺省值
实型说明语句
REAL([KIND=]4) or REAL*4 通常实数的范围是10**-38—10**38之间的7位有效数字 缺省值
REAL([KIND=]8) or REAL*8 等价于双精度型 DOUBLE PRECISION
双精度说明语句
DOUBLE PRECISION
复型说明语句
COMPLEX([KIND=]4) or COMPLEX*8 缺省值
逻辑型说明语句
LOGICAL([KIND=]4) or LOGICAL*4 缺省值
字符型说明语句
CHARACTER([KIND=]1)
◆属性说明
属性关键字 描述 适用范围
ALLOCATABLE 说明动态数组 数组
AUTOMATIC 声明变量在堆栈中而不是在内存中 变量
DIMENSION 说明数组 数组变量
EXTERNAL 声明外部函数的名称 过程
INTENT 说明过程哑元的用意 过程哑元
INTRINSIC 声明一个内部函数 过程
OPTIONAL 允许过程被调用时省略哑元 过程哑元
PARAMETER 声明常量 常量
POINTER 声明数据对象为指针 变量
PRIVATE 限制模块中的实体访问于本块内 常量、变量或模块
PUBLIC 允许模块中的实体被外部使用 常量、变量或模块
SAVE 保存过程执行后其中的变量值 变量或公共块
STATIC 说明变量为静态存储 变量
TARGET 声明变量为目标 变量
VOLATILE 声明对象为完全不可预测并在编译时无优化 数据对象或公共块
◆例如:
REAL*8 a,b*4
REAL(8) a,b
REAL(LEN=8) a,b !种类说明:([KIND=]种别值)
INTEGER,PARAMETER :: Long=SELECTED_REAL_KIND(9,99) !属性说明
REAL :: A=2.8_LONG, B=1.23456789E60_LONG
LOGICAL(KIND=2),DIMENSION(1:10) :: X !同DIMENSION*2 X(10) ??
CHARACTER(LEN=12,KIND=1) :: A,B
CHARACTER(KIND=1,LEN=12) :: A,B
CHARACTER(12,1) :: A,B
CHARACTER*12 :: A,B
CHARACTER(LEN=*),PARAMETER :: C_NAME='GIRL' !*号表示长度暂不确定
CHARACTER(LEN=*),PARAMETER :: C_NAME='BOY'
CHARACTER(LEN=12) :: A,B*5,C,D*7,E !变量名后标出自己的特有长度
◆赋初值:
DATA 变量名表1/初值表1/[[,]变量名表2/初值表2/…]
例如:
DIMENSION A(10,10)
DATA A/100*1.0/ ! 按数组变量名统一初始化(重复次数*常数值)
DATA A(1,1), A(10,1), A(3,3) /2*2.5, 2.0/ ! 按数组元素逐个初始化
DATA ((A(I,J),I=1,5,2),J=1,5) /15*1.0/ ! 按隐DO循环初始化
DATA cstuff/(-1.0,-1.0)/ !复数初始化
CHARACTER (LEN=10) name !字符串初始化
CHARACTER BELL, TAB, LF, FF, STARS*6
CHARACTER*8 help
DATA name,STARS /'Zhang Fei','****'/
DATA BELL,TAB,LF,FF /7,9,10,12/ ! 用ACSII控制字符码赋于字符变量
DATA help(1:4),help(5:8) /2*'HELP'/ ! 用字符子串分段赋值
duiyul输入的数据可以是.TRUE.(真)或.FALSE.(假),也可以是以T或F字母开头的任何字符串
- 【数组】
!-----------------------------------------------------------------------
real a(10)
REAL A(10,2,3) ! 类型说明
DIMENSION A(10,2,3) ! DIMENSI0N语句
ALLOCATABLE B(:,:) ! ALLOCATABLE语句
POINTER C(:,:,:) ! POINTER语句
REAL,DIMENSION(2,5):: D ! 类型说明中的DIMENSION属性
REAL,ALLOCATABLE:: E(:,:,:) ! 类型说明中的ALLOCATABLE属性
REAL,POINTER:: F(:,:) ! 类型说明中的POINTER属性
!-----------------------------------------------------------------------
数组的秩至少是1。如果没有下标则指整个数组。下标必须用逗号隔开,可以用整型常量、变量或表达式,函数。
例如A指整个数组,A(1)指数组A的第1个元素,A(3:4)指数组A的第3和第4个元素,A(1:10:2)指的是数组A的第1,3,5,7,9个元素。数组片段本身也是数组。
◆三元下标:[下界]:[上界][:步长]。默认分别为最小、最大下标,步长默认为1。全部省略指数组全长。
例:
!-----------------------------------------------------------------------
REAL A(10)
A(1:5:2)=3.0 !把元素A(1),A(3),A(5)置为3.0
A(:5:2)=3.O !把元素A(1),A(3),A(5)置为3.0,因为缺省下界为1
A(2::3)=3.O !把元素A(2),A(5),A(8)置为3.0,因为上界缺省值为10
A(7:9)=3.0 !把元素A(7),A(8),A(9)置为3.0,因为缺省步长为1
A(:)=3.0 !和A=3.0相同,将A的所有元素置为3.0
!-----------------------------------------------------------------------
◆向量下标
向量下标是一个一维整数数组(即向量),它可以从整个数组中选择片段。以任何顺序来指定数组元素。
例:
!-----------------------------------------------------------------------
REAL A(10),B(5,5)
INTEGER I(4),J(3)
I=(/5,3,8,2/) !定义向量I
J=(/3,1,5/) !定义向量J
A(I)=3.O !设置元素A(5),A(3),A(8),A(2)的值,同A(/5,3,8,2/)
B(2,J)=3.O !设置元素B(2,3),B(2,1)和B(2,5)的值
!-----------------------------------------------------------------------
例:
INTEGER :: a(4)=(/0,1,2,3/),b(3)=(/1,4,3/)
则a(b)与a同类型,与b同形状,取值为(/0,3,2/)。a(b)可以不是数组片段,而是更大的数组。如上面b为(/2,3,2,3,2,3/)时,a(b)为(/1,2,1,2,1,2/)。 (多对一数组片段,不可以在等号左边被赋值!)
!-----------------------------------------------------------------------
例:
CHARACTER(1) :: symbol(0:1)=(/'F','M'/)
INTEGER :: bit(100)
若bit的元素列为0001101100111...,则symbol(bit)是用{F,M}字符构成的100字节的字符型数组FFFMMFMMFFMMM...。
!-----------------------------------------------------------------------
◆显式形状(Explicit-shape)数组
Dimension ([下界:]上界[,[下界:]上界]…)
维界可以是常数或变量
◆自动(Automatic)数组
用于子程序中的显型数组,维界可用变量表示,例:
!-----------------------------------------------------------------------
SUBROUTINE EXAMPLE(N,R1,R2)
DIMENSION A(N,5),B(10*N)
……
N=IFIX(R1)+IFIX(R2)
!-----------------------------------------------------------------------
此例中的A和B都是自动数组。子程序被调用时,数组A和B的上界通过传入的变量N来确定,而以后N的值的变化对A和B的大小不会有影响。
◆可调(Adjustable)数组
一个主程序的显型数组,作为子过程的一个哑元, 维界是哑元变量,或者常量。需要在子程序中用Dimension重新声明。例:
!-----------------------------------------------------------------------
DIMENSION A1(10,35)
……
SUM1=THE_SUM(A1,10,35)
END
FUNCTION THE_SUM(A,M,N)
DIMENSION A(M,N)
SUMX=0.0
DO J=1,N
DO I=1,M
SUMX=SUMX+A(I,J)
END DO
END DO
THE_SUM=SUMX
END FUNCTION
!-----------------------------------------------------------------------
◆假定形状(Assumed-shape)数组
作为子过程的一个哑元, 通过子程序来确定数组的维界(部分或者全部)
例:
!-----------------------------------------------------------------------
SUBROUTINE ASSUMED(A)
REAL A(:,:,:) !数组A的秩为3,每一维的长度待定。当过程被调用时A将从传递的数组获得形状:
REAL X(4,7,9)
CALL ASSUMED(X)
!-----------------------------------------------------------------------
于是A获得了数组维界(4,7,9),实际数组和假定形状数组的值必须相同。如果上面过程中数组声明了A(3:,0:,-2:),以哑元X(4,7,9)调用过程时,数组A的实际维界是A(3:6,0:6,-2:6)。
应用假定形状数组为哑元的过程时必须有显式的接口INTERFACE语句。
例:
!-----------------------------------------------------------------------
INTERFACE
SUBROUTINE SUB(M)
INTEGER M(:,1:,5:)
END SUBROUTINE
END INTERFACE
INTEGER L(20,5:25,10)
CALL SUB(L)
END
!-----------------------------------------------------------------------
在此例中数组M的维界是(1:20,1:21,5:14)。
◆假定大小(Assumed-size)数组
这种数组是在过程中的哑元,它从实际传递过来的数组获得数组大小。除了最后一维的上界以外,其它所有特征(秩,长度和维界)都必须指定。声明一个假定大小数组时,最后一个的上界用星号*表示。它的一般形式是:([显型维界,][显型维界,]...[下界:]*)。
例:
!-----------------------------------------------------------------------
SUBROUTINE ASSUME(A)
REAL A(2,2,*)
REAL X(7)
CALL ASSUME(X)
!-----------------------------------------------------------------------
则数组X的元素与数组A的对应顺序是:
X(1):A(1,1,1)
X(2):A(2,1,1)
X(3):A(1,2,1)
X(4):A(2,2,1)
X(5):A(1,1,2)
X(6):A(2,1,2)
X(7):A(1,2,2)
A的第三维不是完整的,所以数组X不能作为哑元传递。
◆延迟形状(Deferred-shape)数组
可分配数组必须以延迟形状的形式来声明。它每一维的长度只有在分配数组才被确定。声明迟形数组时,秩由冒号确定,但长度是未知的。
例:
!-----------------------------------------------------------------------
REAL,ALLOCATABLE:: A(:,:,:)
INTEGER,ALLOCATABLE,TARGET:: K(:)
!-----------------------------------------------------------------------
可分配数组可由下列方式声明:使用ALLOCATABLE语句、DIMENSION语句、TARGET语句或在类型声明中使用ALLOCATABLE属性。如果迟形数组以DIMENSION语句或TARGET语句声明,则在其它语句中必须给出ALLOCATABLE属性。
在迟形数组的大小、形状和维界没有确定之前,其任何部分都不能被引用,可分配数组的大小、形状和维界在ALLOCATE语句执行时才被确定。
例:
!-----------------------------------------------------------------------
INTEGER,ALLOCATABLE:: A(:,:)
REAL,ALLOCATABLE,TARGET:: B(:,:),C(:)
ALLOCATE(A(2,3),C(5),B(SIZE(C),12))
!-----------------------------------------------------------------------
◆数组赋值 (按列存储,从左到右) A(1,1) A(2,1) A(1,2) A(2,2)
A=0
A(1:20)=A(20:1:-1) ! 将A数组元素值倒序重排
◆数组构造器是由括号和斜线之间的一系列值或隐DO循环组成。其一般形式为:(/取值列表/)。取值列表可以是标量,隐DO循环或任意秩的数组。
例:
INTEGER A(6)
A=(/1,2,3,4,5,6/) ! 斜杠与括号间不能有空格
C1=(/4,8,7,6/) ! 标量表示
C2=(/B(I,1:5),B(I:J,7:9)/) ! 数组表示
C3=(/(I,I=1,4)/) ! 隐DO循环
C4=(/4,A(1:5),(I,I=1,4),7/) ! 混合表示
◆用方括号代替括号和斜线,例如下面两个数组构造器是等价的:
INTEGER C(4)
C=(/4,8,7,6/)
C=[4,8,7,6]
◆冒号三元下标(代替隐DO循环)来指定值的范围和步长,例如下面两个数组构造器是等价的:
例:INTEGER D(3)
D=(/1:5:2/) ! 三元下标格式
D=(/(I,I=1,5,2)/) ! 隐DO循环格式
◆数组运算
!-----------------------------------------------------------------------
A=B ! 并行处理
do i=1,n
A(i)=B(i)
end do !串行处理
!-----------------------------------------------------------------------
◆WHERE构造
WHERE语句的一般形式为:WHERE(屏蔽表达式) 赋值语句
WHERE构造的一般形式为:
!-----------------------------------------------------------------------
[构造名:] WHERE(数组逻辑表达式1)
[块]
[ELSEWHERE(数组逻辑表达式2) [构造名]
[块]]
[ELSEWHERE [构造名]
[块]]
END WHERE [构造名]
!-----------------------------------------------------------------------
◆FORALL构造
FORALL是F95的新增功能。它是数组屏蔽赋值(WHERE语句和构造)功能的一对一元素的推广,其方式有FORALL语句和FORALL构造。
FORALL语句的一般形式为:FORALL(循环三元下标[,循环三元下标]…[,屏蔽表达式]) 赋值语句
FORALL构造的一般形式为:
!-----------------------------------------------------------------------
[构造名:] FORALL(循环三元下标[,循环三元下标]…[,屏蔽表达式])
[块]
END FORALL [构造名]
!-----------------------------------------------------------------------
屏蔽表达式是数组逻辑表达式,缺省值为.TRUE.。块是赋值语句,或为WHERE语句或构造,或为FORALL语句或构造。
循环三元下标的形式为:循环变量=下界:上界[:步长]。循环变量是整型的。步长不能为0,缺省值为1。
◆函数名称 描述
ALL(mask[,dim]) 判断全部数组值在指定维上是否都满足mask的条件
ANY(mask[,dim]) 判断是否有数组值在指定维上满足mask的条件
COUNT(mask[,dim]) 统计在指定维上满足mask的条件的元素个数
CSHIFT(array,shift[,dim]) 进行指定维上的循环替换
DOT_PRODUCT(vector_a,vector_b) 进行两个向量的点乘
EOSHIFT(array,shift[,boundary][,dim]) 在指定维上替换掉数组末端,复制边界值到数组末尾
LBOUND(array[,dim]) 返回指定维上的下界
MATMUL(matrix_a,matrix_b) 进行两个矩阵(二维数组)的乘积
MAXLOC(array[,dim][,mask]) 返回数组的全部元素或指定维元素当满足mask条件的最大值的位置
MAXVAL(array[,dim][,mask]) 返回在指定维上满足mask条件的最大值
MERGE(tsource,fsource,mask) 按mask条件组合两个数组
MINLOC(array[,dim][,mask]) 返回数组的全部元素或指定维元素当满足mask条件的最小值的位置
MINVAL(array[,dim][,mask]) 返回在指定维上满足mask条件的最小值
PACK(array,mask[,vector]) 使用mask条件把一个数组压缩至vector大小的向量
PRODUCT(array[,dim][,mask]) 返回在指定维上满足mask条件的元素的乘积
RESHAPE(source,shape[,pad][,order]) 使用顺序order和补充pad数组元素来改变数组形状
SHAPE(source) 返回数组的形状
SIZE(array[,dim]) 返回数组在指定维上的长度
SPREAD(source,dim,ncopies) 通过增加一维来复制数组
SUM(array[,dim][,mask]) 返回在指定维上满足mask条件的元素的和
TRANSPOSE(matrix) 转置二维数组
UBOUND(array[,dim]) 返回指定维上的上界
UNPACK(vector,mask,field) 把向量在mask条件下填充field的元素解压至数组
◆用ALLOCATE语句动态分配数组
ALLOCATE语句动态创建可分配数组,使内存和对象相联系。分配的对象可以被命名为任何有ALLOCATABLE属性的变量。它的一般形式为:
ALLOCATE(数组名[维界符][,数组名[(维界符[,维界符...])] ] ...[,STAT=状态值])。
例:
!-----------------------------------------------------------------------
REAL A(:),B(:,:,:)
ALLOCATABLE A,B
ALLOCATE(A(-
◆数组查询:
数组形状 shape(a) m n
数组大小 size(a) mxn
数组下限 lbound(a) 1 1
数组上限 ubound(a) m n
- 【派生类型】
!--------------------------------------------------------
TYPE[,访问属性说明::] 派生类型名
成员1类型说明
成员n类型说明
END TYPE [派生类型名]
!--------------------------------------------------------
TYPE是关键字,表示派生类型定义开始。访问属性说明关键字是PUBLIC或PRIVATE,默认值是PUBLIC,即访问方式是共用的。PRIVATE表示该类型是专用的,这个关键字只有当TYPE块写在模块说明部分中时,才允许使用。如果不是在模块内定义的派生类型,不可使用PRTVATE。
:
!--------------------------------------------------------
TYPE CLASS_TYPE !年级_类
CHARACTER(LEN=50) :: DEPARTMENT, MAJOR !系,专业
END TYPE CLASS_TYPE
TYPE SCORES_TYPE !成绩_类
INTEGER(1) :: MATH, PHYSICS, ENGLISH
END TYPE SCORES_TYPE
TYPE STUDENT_TYPE
SEQUENCE !按定义的顺序储存各个成员
INTEGER(4) :: NUMBER !学号
TYPE(CLASS_TYPE) :: CLASS !班级_类(系,专业)
CHARACTER(LEN=10) :: NAME, ADDRESS !姓名,地址
TYPE(SCORES_TYPE) :: SCORES !分数_类
END TYPE STUDENT_TYPE
TYPE(STUDENT_TYPE),DIMENSION(40):: STUDENT !学生数组(40)有类别
TYPE(STUDENT_TYPE) Myself
!--------------------------------------------------------
其中:STUDENT(6)%SCORES%PHYSICS !第6个学生的物理成绩,该类型成员值
初始化一个成员:STUDENT(666666, 'BWL', '2004', 'John', 'Str. 1', 100, 100, 100) !该类型的值
用DATA初始化:DATA Myself/STUDENT(666666, '2004', 'BWL', 'John', 'Str. 1', 100, 100, 100)/
个别元素初始化:DATA Myself%NUMBER, Myself%ENGLISH/88888, 99/
显示初始化: TYPE(REPORT),PARAMETER :: SHE=STUDENT(0,'','','','',0,0,0)
◆结构构造函数(派生类型名)
ME%CLASS=CLASS_TYPE("2004","BWL") !引用CLASS_TYPE的结构构造函数,进行赋值
SHE=STUDENT_TYPE(22222,ME%CLASS,'Sherry','Str. 2',SCORES_TYPE(60,60,60))
- 【算术运算】
单项运算:(例 -a)
2项运算:加(+),减(-),乘(*),除(/),乘方(**)
乘方按“先右后左”,其它按“先左后右”原则
运算的优先顺序::① 括号 > ② 函数 > ③ ** > ④ * / > ⑤ + -
- 【关系运算】优先级低于【算术运算】
.GT. >
.GE. >=
.LT. <
.LE. <=
.EQ. ==
.NE. /=
- 【逻辑运算】优先级低于【关系运算】
.AND.
.OR.
.NOT. (单元素操作 .NOT.A)
.EQV.
.NEQV.
顺序是:.NOT. > .AND. > .OR. > .EQV. 和 .NEQV.
- 【判断IF构造】 IF构造中的每一个块,都可以嵌入一个完整的构造。但不可跨越2个块。嵌套IF需要加构造名。
!--------------------------------------------------------
[构造名:] IF (逻辑) THEN
...
ELSE IF (逻辑) THEN [构造名]
...
ELSE [构造名]
...
END IF [构造名]
!--------------------------------------------------------
块IF的执行步骤为:先执行块IF语句,求出逻辑表达式的值,如果此值为“真”,则将流程转到then块。执行then块中各个执行语句。执行完then块后跳过ELSE语句和else块,流程转到END IF语句处。如果逻辑表达式的值为“假”,则流程跳过then块,转到ELSE语句及else块。执行完else块以后流程转到END IF语句。
- 【GOTO循环】慎用!
!--------------------------------------------------------
GOTO (语句标号)
!--------------------------------------------------------
- 【DO循环】
!--------------------------------------------------------
[构造名:] DO [[标号][,]] 循环变量=初值式,终值式[,增量式]
...
END DO [构造名]
!--------------------------------------------------------
循环次数可以从循环初值、终值和步长计算出来:次数=INT((终值-初值+增量)/增量)
例:对于DO I=1.5,3.6,1.2 不要根据INT((3.6-1.5+1.2)/1.2)=2而认为循环次数为2,而应当先将实型量转化为整型量,即变成相当的循环语句 DO I=1,3,1 其循环次数为3次而不是2次。
例:对于DO X=1.5,3.6,1.2 由于循环变量不是整型的而是实型的,它的循环次数为2次。X取值分别是1.5,2.7。
◆隐DO循环只能作为输入输出表的一部分出现
(I/O列表,循环变量名=初值,终值,增值)
例如: READ *,(VALUE(I),I=1,20)
表示读入VALUE(1),VALUE(2),…,VALUE(20)的值。
WRITE(*,*) (A,B,N=1,5)
表示在当前设备用默认格式重复输出A、B的值5次。
隐DO表可以嵌套,
例如:PRINT *, ((A(I,J), I=1,3), J=1,3)
◆无循环变量的DO构造
!--------------------------------------------------------
[构造名:] DO
...
END DO [构造名]
!--------------------------------------------------------
◆跳出循环方法:
EXIT [DO构造名]
CYCLE [DO构造名]
没有构造名,则默认跳出为最内层的循环
可以用IF语句进行判断:
!--------------------------------------------------------
[构造名:] DO
...
IF(逻辑表达式) Exit/CYCLE
...
END DO [构造名]
!--------------------------------------------------------
◆DO WHILE 当型循环
!--------------------------------------------------------
[构造名:] DO WHILE (逻辑表达式)
...
END DO [构造名]
!--------------------------------------------------------
- 【多重选择CASE构造】
!--------------------------------------------------------
[构造名:] SELECT CASE(case表达式)
CASE(case选择符) [构造名]
...
[CASE DEFAULT [构造名]
...
END SELECT [构造名]
!--------------------------------------------------------
程序执行时,CASE构造的控制机制是:(1)控制进入CASE构造后,先计算情况表达式的值;(2)如果第一个CASE语句选择符值与情况表达式值相等则执行语句块1,转出口;(3)如第一个选择符值不为情况表达式的值,再查下一个CASE语句的选择符值,满足执行语句块2,转出口,不满足再查下一个CASE语句的选择符值,直至全部情况选择符值都检查完;(4)如果全部情况选择符值都不符情况表达式的值,且又有CASE DEFAULT语句,则执行该语句后的DEFAULT块,否则直接转出口。
其中,case表达式是整型、字符型或逻辑型表达式,不能是实型和复型表达式。
(值表) 表示等于该值,各值之间用逗号分开
(下界:) 表示大于或等于该值
(:上界) 表示小于或等于该值
(下界: 上界) 表示在这两个值之间 (包括等于)
- 【READ,WRITE 输入输出】
READ *, a, b
READ (*,*) a, b
PRINT *, 'a=' , a , 'b=' , b
WRITE *,
WRITE (*,*)
WRITE (*,/)
Fortran支持两种文件的访问方式(顺序访问和直接访问)和三种文件的结构(有格式、无格式、二进制)。顺序访问或直接访问可以用于这三种结构的文件进行的每一种。因此,共有6种文件类型。
◆格式化文件,记录数据内容的记录是以ASCII字符的方式存在的,每一条记录是以ASCII码中的回车符CR(0D)加换行符LF(0A)来结束的,可以用文本编辑软件打开格式文件并直接看懂其内容。OPEN语句默认的打开文件是格式文件
◆无格式文件,由一系列物理块组成的记录组成,所存储的记录序列的存放方式与其在内存中的存放非常相似,所以在输入输出时几乎不需作转化。
◆二进制文件,是处理最快、最简洁的一种文件,也是最紧凑的存储格式,适合于大批量数据的存储。在程序中可以用带有FORM=’BINARY’选项的OPEN语句来打开或建立二进制文件。
◆顺序文件,数据必须一个记录接一个记录地按顺序被访问。也就是说,程序中要读写第N条记录时,必须至少已对前面的N-1记录进行过读操作。
◆直接访问文件,记录可以以任意顺序进行读写操作。文件中的记录从1开始连续编号,记录的长度是通过OPEN语句中的RECL选项来描述的。直接文件中的记录是通过指定要访问的记录号来实现的。因此,如果想要实现数据的随机访问可以使用直接访问文件。直接文件应用的一个最常见的实例就是数据库。直接文件中的每个记录的长度必须相等。用直接方式建立的文件可以使用顺序方式打开进行读操作。用顺序方式建立的文件,只要记录长度相等,也可以用直接方式打开进行读操作。
!-----------------------------------------------------------------------------------------------
◆格式化顺序文件(默认)
—个格式化文件是一个由按顺序写到文件中的有格式记录序列组成的,当要对文件进行读操作时,读取的顺序就是记录在文件中的存放顺序。文件中记录的长度不一定相同,记录也可以是空的。记录用回车符(0DH)和换行符(0AH)分开。
◆格式化直接文件
在格式化直接文件中,所有记录的长度都相同并且可以以任意顺序读写。记录的长度由OPEN语句中的RECL=选项指定,该长度应该大于或等于最长的记录中的字节数。CR和LF是分隔符,不包括在RECL中。一旦某个直接访问记录被写入就不能再删除它,但可以覆盖这个记录。在输出到一个格式化直接文件时如果数据没有占满一个记录,则编译系统将在剩下的位置上补以空格,保证文件只包含长度相同的完整的记录。从文件中读数据时,当I/O列表或格式描述符中要读取的数据多于记录中的数据时,编译器也会以空格填充未读数据的变量。可以通过在打开文件的OPEN语句中设置PAD=NO来避免填补空格,此时输入记录必须有和输入列表和格式描述符所要求的一样多的数据,否则会产生错误。PAD=NO对输出没有影响。
◆无格式顺序文件
无格式顺序文件中记录的长度可以不同,文件以130或少于130字节为一个物理块进行组织。每个物理块包含着输入到文件中的数据(最多128字节),编译系统在物理块之间加入两个1字节长的长度值以说明每个记录的起始和结束位置。一个逻辑记录包含一个或多个物理块,其大小可在程序中指定,编译系统会相应地使用需要数量的物理块。
◆无格式直接文件
无格式直接文件是一系列非格式的记录,可以以任意顺序读写记录。记录的长度都相同,由OPEN语句中的RECL=选项指定。没有字节分隔符或其它表示记录结构的字节。
◆ 二进制顺序文件
二进制顺序文件是一系列按同一顺序和同样二进制数个数来读写的值。其中没有记录边界,没有说明文件结构的特殊字节。数据读写时长度和形式都不改变。数据记录的长度可以不等。对于任何输入输出数据,内存中的字节序列就是文件中的字节序列。二进制顺序文件是处理最简洁、速度最快的文件。
◆二进制直接文件
二进制直接文件存储一系列二进制数记录,它们可以按任何顺序访问。与二进制顺序文件不同的是,这些记录的长度是相等的,由OPEN语句中的RECL=选项指定。在二进制直接文件中可以写入部分记录,记录中末使用的部分将以未定义数据填充。
在二进制直接文件中可以只使用一条读或写语句来读写到多于一条的记录,而这样的操作在无格式直接文件中将引发错误。在无格式直接文件中所能进行的一切操作在二进制直接文件中都是合法的,另外,在二进制直接文件中提供了一种不依赖于填充二进制数据O的对记录的某部分进行读写操作的功能。二进制直接文件是所有6类文件中使用最灵活的一类。
◆WRITE语句
!--------------------------------------------------------
WRITE ({[UNIT=]单元|*}[,{[FMT=]格式说明符|[NML=]名称列表组名|*}][,REC=记录号][,IOSTAT=状态变量名][,ERR=错误标号]) [I/O列表]
!--------------------------------------------------------
如果省略UNIT=,则第一个参数必须是“单元”。如果省略了FMT=或NML=,则格式说明符或名称列表组名必须是第二个参数(格式化文件)。其后的几项参数次序可以任意。
单元:外部文件时是一个指定设备号的整型表达式,内部文件时是一个字符串、变量、数组、数组元素或非字符数组。
格式说明符:对于格式写操作是必需的,非格式写操作时不能有。
名称列表组名:如果它被说明,则I/O列表必须省略。
记录号:一个整数表达式指定要被写的记录序号,仅用于直接文件。文件中的第一条记录的记录号为1,缺省值为文件中的当前位置。
状态变量名:一个整型变量、数组元素。当无错误时,它返回值为0,有错误时则返回错误信息号。
错误标号:在同一个程序单位中的一个可执行语句的标号。如果指定了它,I/O错误将把控制传递给此标号处的语句,省略时取决于状态变量名的存在与否。
◆READ语句
!--------------------------------------------------------
READ({[UNIT=]单元|*}[,{[FMT=]格式说明符|[NML=]名称列表组名|*}] [,REC=记录号][,IOSTAT=状态变量名][,ERR=错误标号][,END=文件结束标号][,EOR=记录结束标号]) [I/O列表]
!--------------------------------------------------------
文件结束标号:读到文件结束记录时把控制传递给标号处的语句。
记录结束标号:读完一个记录时把控制传递给标号处的语句。
◆I/O列表 在内存中的变量和外部设备及外部文件之间传递数据
格式化I/O (见Format语句)
直接列表I/O 一系列由逗号或空格分开的值,分隔符(逗号,斜杠或空格),斜杠(/)将结束输入,逗号间为空值
名称列表I/O NAMELIST /名称列表组名/变量列表[[,]/组名/变量列表]...
例如:名称列表输出:WRITE(*,[NML=]namelist)
◆OPEN语句详细说明
OPEN([UNIT=]unit[,ACCESS=access][,ACTION=action][,BLANK=blanks][,BLOCKSIZE=blocksize][,CARRIAGECONTROL=carriagecontrol][,DELIM=delim][,ERR=err][,FILE=file][,FORM=form][,IOFOCUS=iofocus][,IOSTAT=iostat][,PAD=pad][,POSITION=position][,RECL=recl][,SHARE=share][,STATUS=status])
其中的各项参数的意义及取值如下:
1) UNIT:设备号说明。unit是大于或等于0的正整数,设备号说明是OPEN语句的第—项时可以省略"UNIT="
2) ACCESS:存取方式说明。access是字符串表达式:
APPEND 追加方式
SEQUENTIAL 顺序访问方式
DIRECT 直接访问方式
当省略此说明项时为顺序访问方式。
3) ACTION:描述文件的读写属性。action是字符串表达式:
READ 文件为只读方式打开
WRITE 文件为只写方式打开
READWRITE 文件为可读写方式打开
当省略此说明项时,文件打开顺序:READWRITE->READ->WRITE。
4) BLANK:说明数据格式输入字段中空格的含义。blank是字符串表达式:
NULL 空格忽略不计,相当于在格式描述符中的BN编辑符
ZERO 空格处理成数字0,相当于BZ编辑符
当省略此说明项时为ZERO。此说明只能用于格式输入。
5) BLOCKSIZE:指定以字节为单位的设备缓存的大小,默认值为一4字节整数。
6) CARRIAGECONTROL:指明处理文件中的第一个字符的方式,其值为字符串表达式:
Fortran 对第一个字符作一般的Fortran解释
LIST 指出在文件的每两个记录之间有—个空格
默认状态下,对于连接到打印机和显示器这样的设备,设置值为Fortran,对于连接到文件的设备,
设置值为LIST。当FORM被设成UNFORMATTED和BINARY时,其值被忽略。
7) DELIM:指明分隔直接列表或格式化名称列表记录的方式,其值为字符串表达式:
APOSTROPHE 用单撇号(')分隔
QUOTE 用双撇号(")分隔
NONE 不用分隔符
如果在OPEN语句中设置了分隔符,则在文件中的单撇号和双撇号都是成对出现的。
8) ERR:出错处理说明。其值是同一程序中的一条语句的标号,当OPEN语句执行出错时执行此语句。
如果省略该项,则出错时给出出错信息并终止运行。
9) FILE:文件名。是一字符串表达式,可以是空、合法的数据文件名字、设备名字或是作为内部文件的变量。
在WinNT/9x中允许使用长度大于8的文件名和长度大于3的文件扩展名。省略此项时,编译器将自动产生
一个文件名唯一的临时文件,这个临时文件将在结束运行或与文件连接的设备关闭后被删除掉。
10) FORM:记录格式说明。form是字符串表达式:
FORMATTED 记录按有格式存放。
UNFORMATTED 记录按无格式存放。
当省略此说明项时为:对顺序文件是有格式的;对直接文件是无格式的。
11) IOFUS:指出一个新Quickwin子窗口是否为活动窗口,其值为逻辑值。缺省值为真。
12) IOSTAT:出错状态说明。iostat是—个缺省长度为4的整形变量。当执行此OPEN语句时系统给变量赋值:
零 没有发生错误
负数 文件结尾
正数 发生错误,其值视具体计算机系统而定
若省略该项则没有此功能。
13) PAD:从格式化文件中记录的数据少于要读取的数据时,是否用空格来填充没有从记录中读到数据的变量。
pad是字符串表达式:
YES 填充(默认值)
NO 不填充
14) POSITION:指定打开顺序文件的访问位置,position是字符串表达式:
ASIA 已被连接的文件的访问位置是固定的,未被连接的文件的访问位置是文件的开始处。
REWIND 把文件的访问位置定在文件的开始处(文件己存在)。
APPEND 把文件的访问位置定在文件的末尾处(文件己存在)。
对于一个新文件,文件的访问位置总是被定在文件的开始处。
15) RECL:记录长度(单位为字节)说明。recl是指定的正整型量或算术表达式,用来指定直接文件中的
每条记录的字节数,或顺序文件中的记录的最大长度。
16) SHARE:指明当文件打开时是否实现文件的锁定。share是字符串表达式:
DENYRW 动态读写模式。不允许其他的进程打开这个文件。
DENYWR 动态写模式。不允许其他的进程以写的方式打开这个文件。
DENYRD 动态读模式。不允许其他的进程以读的方式打开这个文件。
DENYNONE 默认的非动态模式。允许其他的进程打开这个文件。
17) STATUS:文件状态说明。status是字符串表达式:
OLD 表示指定的文件是已经存在的老文件。
NEW 表示指定的文件尚不存在。
SCRATCH 表示与设备号相连接的文件在关闭时将被自动删除。该文件为程序运行过程的一个临时文件。
REPLACE 表示替换一个有相同名字的文件,如果没有同名的文件存在,将产生一个新文件。
UNKNOWN 表示文件可以是已存在的或不存在的。系统打开文件状态的次序为:OLO->NEW->创建新文件。若省略该项时默认的状态为UNKNOWN。
◆CLOSE语句
CLOSE语句解除设备号与文件的连接,又称关闭文件。它的一般形式为:
CLOSE([UNIT=]unit[,ERR=err][,IOSTAT=iostat][,STATUS|DISPOSE|DISP=status])
其中除STATUS以外的各项参数的意义及取值与OPEN语句中的相同。STATUS是文件关闭后状态说明,其值是一字符串:
DELETE 与设备连接的文件不保留,被删除
KEEP(或SAVE) 与设备号连接的文件保留下来不被删除
PRINT 将文件递交给打印机打印并被保留(仅对顺序文件)
PRINT/DELETE 将文件递交给打印机后被删除
SUBMIT 插入一个进程以执行文件
SUBMIT/DELETE 插入一个进程以执行文件,当插入完成后被删除
默认设置将删除带有SCRATCH属性的临时文件,对其它文件为KEEP。
◆文件指针定位语句
REWIND语句:
称为反绕语句,它使指定设备号的文件指针指向文件的开头,通常用于顺序文件的操作。它的一般形式为:
REWIND {unit|([UNIT=]unit[,ERR=err][,IOSTAT=iostat])
BACKSPACE语句:
称为回退语句,它使指定设备号的文件指针退回一个记录位置,一般用于顺序文件。它的一般形式为:
BACKSPACE{unit|([UNIT=]unit[,ERR=err][,IOSTAT=iostat])
除了以下几种情况外,使用BACKSPACE语句正好使文件的指针向前移动一条记录:本条记录前再没有记录时文件指针的位置不变;文件指针的位置在一条记录的中间时,文件指针移到本条记录的开始处;本记录的前—记录是文件结束记录时,文件指针移到文件结束记录之前。
◆内部文件
read(str,*) name !从str字符串中读取名字
read(str,*) i,j,k !从str字符串中读取数字i,j,k, zB.atr=" 1 2 3",则i=1,j=2,k=3
write(str,'("Test", I4.4, "dat")') 15 !str="Test0015.txt"
- 【FORMAT语句】I/O操作方式之一
!--------------------------------------------------------
WRITE(*,100) Number
100 Format(I4) !FORMAT语句标号
!--------------------------------------------------------
ASSIGN 100 TO Mystyle
WRITE(*, Mystyle) Number
100 Format(I4) !整型变量名
!--------------------------------------------------------
Mystyle='(I4)' !字符表达式或变量
WRITE(*,Mystyle) Number
!--------------------------------------------------------
WRITE(*,'(I4)' ) Number !格式列表
!--------------------------------------------------------
CHARACTER(6) array(3)
DATA array/'(I5’, ',I4', ',A16) '/ !也可以用数组
WRITE(*,array) I,I, "Very good!"
!--------------------------------------------------------
可重复的编辑符
◆I编辑符 Iw[.m] w指定字段宽度,m表示需要输出的最少数字位数,不足添0
◆F编辑符 Fw.d w指定字段宽度,d是输出数据的小数位数
◆E编辑符 Ew.d w仍为字段宽度,d为以指数形式出现的数据的数字部分的小数位数 w≥d+7
◆G编辑符 Gw.d 绝对值小于0.1或大于10**d的数用E格式,否则用F格式,有效位数为d位
◆D编辑符 Dw.d 双精度
◆L编辑符 Lw 值为“真”的,在输出一个字母T,“假”则以一个字母F表示,w>1时左边补空格
◆A编辑符 A[w] 字符串的长度小于w,则左边补空格,不指定字段宽度w则按字符变量的的长度截取
◆B、O、Z编辑符 二进制(B)、八进制(O)和十六进制(Z) Bw[.m],Ow[.m],Zw[.m]
◆EN、ES编辑符 工程计数法(EN)和科学计数法(ES) ENw.d[Ee] ESw.d[Ee]
下面的为不可重复的编辑符
◆引号"编辑符 ' '和" "。例如WRITE(*, '('I''m a boy')') 或 WRITE(*, '("I 'm a boy")')
◆H编辑符 nH字符串, 例如WRITE(*,'(9HI 'm a boy)')
◆X编辑符 输出时产生空格
◆斜杠/编辑符 从下一行开始输出下一个记录,用n个连续的斜杠,可以达到输出n-1个空行的效果
斜杠只表示结束本行输出,当扫描到右括号而列表中已无数据项时,输出即告结束。
◆\和$编辑符 输出一个记录行后取消回车符,例如Write(*,'("Please Enter Your Age =",$)')
◆T编辑符 Tn,TLn,TRn 分别为第n个字符,左移和右移n个字符
◆:编辑符 当I/O列表中没有更多的数据顶时,冒号(:)编辑符使格式控制结束
◆P编辑符 改变小数点位置
◆S编辑符 SP输出正号,SS不输出
◆BN,BZ编辑符 BN忽略数字输入字段中内嵌和后续空格,BZ使开头、结尾空格和分散空格为零
空格式format(),用于WRITE中表示回车换行,READ中表示跳过相邻的下一个记录
“输入数据自带小数点优先”原则,F、E、EN、ES、G和D编辑下的输入中,输入区域的显式小数点将覆盖编辑描述符中对小数点位置的指定。例如,READ(*,’(F4.2)’) x当输入123.4时,x=123.4而非按格式指定的23.40。
- 【一些说明】
◆Fortran允许使用的字符如下:
英文字母 :A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
阿拉伯数字 :0 1 2 3 4 5 6 7 8 9
特殊符号 :空格 = + - * / ( ) , . ': " ! % & ; < > $ ? _ (F90中新增的字符)
◆F90的语句顺序,
◆F90的运算优先级,◆F90的常用函数,
◆声明时用::表示声明的变量的属性已经声明完全, 左边为变量的类型、种别、属性,右边为变量
◆整数相除的商也是整数:5/2=2 , 1/2=0
◆在判断两个实数是否相等时,最好判断|a-b|< ε
◆取得随机数的方法:
!--------------------------------------------------------
CALL RANDOM_SEED
CALL RANDOM_NUMBER(a) ! a=0~1
!--------------------------------------------------------
- 【一些建议】
◆开始编制一个程序前,做好前期准备,画,或者用伪代码描述整个过程的算法。
◆用Program语句,并且给其命名。
◆用IMPLICT NONE语句,并自己声明所需要的每一个变量,避免出错。
◆对于多重循环采用标签