前言
Fortran学习初步
先学会基本用法完成任务即可
一、Fortran?
Fortran 是一门编译型的编程语言
,是For
mula Tran
slation 的缩写,特产是科学计算
编译器:编译源代码到可执行文件
基本步骤:编译&链接
得到可执行文件,然后运行
编译 -c,链接-o 得到可执行文件
二、错误
编译、链接错误 编译器和链接器
运行时错误:运行时库(Run-time Library)抛出
最难解决的错误:不报错,结果不符合预期要求 debug
linux需要加 -fcheck=bounds
参数
1.编译错误
syntax Error语法错误 compiling
2.链接错误
链接过程linking
main函数只能有一个
3.运行时错误
难以完全解决(设备、用法等等)
调试器 debugger
三、 程序设计基础
3-1 字符集
字符集是指编写Fortran程序时所能使用的字符及符号
符号 | 范围 |
---|---|
英文26字母 | A~Z以及a-z(不区分大小写) |
数字 | 0-9 |
22个特殊字符 | :=±*… |
Fortran编译器只认得大写字母
,小写会自动转大写
3-2书面格式
有两种,分别为Free-format(自由格式)和Fixed-format(固定格式)
固定格式现在已经废止,推荐使用自由格式
固定格式 | 自由格式 | |
---|---|---|
英文 | FIxed-format | Free-format |
扩展名 | .for,.f… | .f90,.f95,.f03… |
语法 | F66,F77,F90,F95,F03,F08 | F66,F77,F90,F95,F03,F08 |
格式 | 代码从第七格开始 | 任意 |
续行 | 在第6格键入非零字符接前一行 | 在前一行最后加入&符 |
行宽 | 72 | 132 |
注释 | 行首打 C 或 c 或 * | 注释前打 ! |
说明 | 不推荐已废止 | 推荐使用 |
3-3数据类型
名称 | 类型 | 长度 | 内存长度 |
---|---|---|---|
整数(INTEGER) | 长整型 | -231+1~231 | 32 bits/4 bytes |
短整型 | -215+1~215 | 16 bits/2 bytes | |
浮点数(REAL) | 单精度 | ±3.4*1038~±1.18*10-38 | 4 byte |
双精度 | 15~16位精度 | 8 bytes | |
复数(COMPLEX)a+bi | 单双精度 | 由a,b两个浮点数来控制 | |
字符(CHARACTER) | 文本 | 一符一byte | |
逻辑判断(LOGICAL) | TRUE FALSE,1,0 |
3-4数学表达式
运算符号:需要注意的地方:**连写代表乘幂;*号不可省略
四、输入输出及声明
program ex0401
write(*, *) "Hello"
stop
end
注:Fortran程序通常以PROGRAM描述来开头,紧接一个自定义的程序名称(和文件名无任何关联)
一般建议取名MAIN,明确主程序,在PROGRAM和END之间
stop不要写在主程序外的其他地方,这是终止程序的指令
end 表示程序代码结束
end program
end program ! main 均可
4-1 WRITE
WRITE(*, *) 第一个*代表输出的位置(默认值就是屏幕当前),第二个 *代表不特别设置输出格式
严格写法:
WRITE(UNIT=6,FMT= *)
注意事项
1.执行 WRITE后会自动换行
2.输出双引号连用双引号即可,不需要‘’\‘’转义
print与write类似
print *, "hello"
建议用write
4-2 声明
含义:在程序代码中,程序员向编译器要求预留一些存放数据的内存空间。
语法:
数据类型 变量名
program ex0404
integer a !声明一块内存存储整数,以a命名这块内存,习惯上叫变量
a = 3 ! 将a设置为3,a的值可以是一个右值数学表达式
write(*, *) "a=", a
stop
end
注意点
1.Fortran 不区分大小写,自定义变量也不区分
2.长整型声明语法:integer(kind=4) a
4代表需要4个byte存储这个整数
3.声明同类型变量可以放在同一行 integer a, b, c
4.声明变量时 变量名称不能和program相同,也不要与关键字一致(如write)
5.f90声明语法:integer :: a
两个冒号的含义后面叙述
REAL声明也类似
write新用法
write(*, *) a, "+", b, "=", a+b
!可以放入表达式,输出也可以分几段
Fortran也有许多内脂数学函数,sin,log,指数等等,用的是弧度制
COMPLEX声明 complex :: a, b
! 像一个二维数组,输出是括号括起来的实部虚部。
字符及字符串CHARACTER
声明单字符 character :: a
声明字符串 character([len=]10) :: a
设置字符串内容时的注意点:
双引号封装字符串,可以再字符串内使用单引号,但输出双引号需要连续两个双引号
单引号封装字符串,输出单引号需要连续两个单引号
!!!!!!Fortran对字符串大小写区分!!!!!!
字符串特别用法:
a.改动某一部分(切片)
program ex0413
character(len=20) string
string = "Good morning."
write(*, *) string
string(6:) = "evening."
write(*, *) string
stop
end
切片指定范围,首位从1开始
,范围前后都是闭
,(1, 2)代表首位和下一位。冒号是必须的
b.连接字符串
用两个斜杠//
来连接字符串
Fortran相关字符串运行 | |
CHAR(num) | 返回num所对应字符 |
ICHAR(char) | 返回char所对应编号 |
LEN(string) | 返回声明长度 |
LEN_TRIM(string) | 返回去除尾端后空格的实际长度 |
4-3 输入命令(READ)
语法
program ex04017
integer a, b, c
read([unit=]5, [fmt=]*) a, b, c !由键盘读入整数 可以连续读
write(*, *) a
end
类似write
read([unit=]*, [fmt=]*) 第一个参数是输入设备,第二个参数是输入格式
4-4 格式化输入输出(FORMAT)
program ex0420
integer a
a = 100
write(*, 100) a
100 format(I4)
write(*, *) a
end
输出:
符号 | 含义 | 示例 |
---|---|---|
An | 以n个字符宽度输出字符串 | 超出部分会被略去 |
BN | 输入时:定义文本中空位为没有东西 | |
BZ | 输入时:定义文本中空位代表0 | |
Dn.m | n宽,m位小数输出指数计数浮点数 | 0.100000D-04 |
En.m[Ee] | n宽,m位输出指数计数 ,指数部分e字符 | 0.100000D-04 |
ESn.m[Ee} | n宽,m位输出科学计数 ,指数部分e字符 | 1.000000D-05 |
Fn.m | n宽m位输出浮点数 | 不足前补空格 |
Gn,m[Ee] | n宽输出任意数据 | |
In[.m] | n宽,最少m位输出整数 | n<数字位数显示n个*,m<数字位数前补零 |
Ln | 以n位输出T/F的真假值 | 前补空格 |
nX | 输出向右跳过n个位置 | |
/ | 代表换行 | |
: | 没有数据时结束输出 | |
kP | k控制输入输出的SCALE | |
Tn | 输出位置移动到本行第n列 | |
TLn | 输出位置向左相对移动n列 | |
TRn | 输出位置向右相对移动n列 | |
SP | 数值为正前加+ | |
SS | 取消SP | |
F90新加 | ||
Bn.[m] | 整数换二进制,n宽m位输出 | |
On.[m] | 整数换八进制,n宽m位输出 | |
Zn.[m] | 整数换十六进制,n宽m位输出 |
格式需要用括号括起来,直接放在write命令中,用行号标记也可但不方便
同样格式输出write(*, "3(1xf5.2))" a, b, c
4-5 注意事项
变量
前缀必须是英文字母
,其他位置数字字母下划线
Fortran90支持31位字符为名称
IMPLICIT命令
Fortran变量不一定需要声明。
第一个字母为IJKLMN的变量会被视为整数,其他变量视为浮点数
加入implicit none关闭默认类型
建议关闭
implicit也可以设置默认类型对应前缀特征
常数声明 PARAMETER
语法:
program main
implicit none
real pi
parameter(pi = 3.14159) ! can use: real, parameter :: pi = 3.14159
write(*, "(F4.2)") sin(pi/6)
end
变量初值设置
program main
integer :: a = 1
real :: b = 2.0
complex :: c = (1.0, 2.0)
real, parameter :: pi = 3.14159
end
F90用::
定义变量时可以直接赋值
F77则需要先声明,然后用DATA命令赋初值DATA var, var2... /v1, v2.../
等价声明(EQUIVALENCE)
使用同一个内存地址就是“等价声明”,一改俱改
优点:节省内存;精简代码(尤其数组)
声明在程序中的结构
声明必须放在程序的可执行描述之前,开始数值计算和输入输出时就不能再声明变量
4-6 自定义数据类型
示例:
type :: person !冒号可以省略
character(len=30) :: name
integer :: age
integer :: length
integer :: weight
character(len=80) :: address
end type person
type(person) :: a ! 声明一个person对象
read(*, *) a%name ! 给对象中的name赋值
4-7 KIND使用
占用字节大小,不指定就是默认大小,可以指定长短整型等
可自定义数值的记录位数:
用SELECT_INT_KIND(n) 记录n位整数
用SELECT_REAL_KIND(n,e) n位有效数,e位指数位
五、流程控制与逻辑运算
5.1 IF语句
语法:
IF (Judgment criteria) THEN
...
ELSE IF (...) THEN
...
ELSE IF (...) THEN
...
END IF
写法中
可以省略THEN和END IF
,但仅限于语句只有一条
IF 或 ELSE下的语句可以缩进来区分
多重嵌套可以大小写互用对应,if(…) then end if
5.2 逻辑运算
判断内容 | F90 | F77 |
---|---|---|
相等(EQuivalent) | == | .EQ. |
不相等(Not Equivalent) | /= | .NE. |
大于(Greater Than) | > | .GT. |
大于等于(Greater or Equivalent) | >= | .GE. |
小于 | < | .LT. |
小于等于 | <= | .LE. |
且/交集 | .AND. | |
或/并集 | .OR. | |
逻辑反向 | .NOT. | |
两边逻辑表达式结果相同,就成立 | .EQV. | |
两边逻辑表达式结果不同,就成立 | .NEQV. |
浮点数判断等值尽量不要用==
,可以给一个阈值
5-3 SELECT CASE 语句
简单形式的多重判断
select case(score)
case(90:100)
grade='A'
case(0:89)
grade='B'
case default
grade='?'
end select
根据变量score数值范围来判断落入哪一个case
case范围是前后闭合,因此也就只能用整数、字符、逻辑变量
case(1, 3, 5) 方式是可以的
case(1:)指 >=1的所有情况
case中的判断范围必须是常量
5-4 二进制逻辑运算
IAND
IOR
六、循环
6-1 DO
do counter = 1, lines, 1
!计数器 终止值 计数器增值(默认缺省为1)
...
end do
6-2 DO WHILE循环
do while(Judgment criteria)
...
end do
相当于将计数器写到循环体内部,当不如DO简洁直观
DO来处理已知循环次数的问题
而DO WHILE则处理预先不知道循环次数的问题
(猜数问题)
program main
implicit none
real, parameter :: weight = 45.0 !!! attention the ,
real, parameter :: error = 1e-3
real :: guess = 0.0
do while(abs(guess-weight) > error)
write(*, *) "Weight:"
read (*, *) guess
end do
write(*, *) "You're right"
stop
end
6-3 循环的流程控制
CYCLE
略过循环中cycle后的程序模块,直接进行下一次循环(python的continue)
EXIT
跳出当前循环(Python中的break)
循环署名
integer :: i, j
outter: do i=1, 3
inner: do j=1, 3
write(*, "('(',i2,', ',i2,')')") i, j
end do inner
end do outter
可以与EXIT,CYCLE连用指明跳出哪个循环
七、数组(ARRAY)
数组可以保存多个同类数据串
7.1 基本使用
一维数组
语法:
datatype name (size) ! 最简单
datatype, dimension(size) :: name
三部分:数据类型 数组名 数组大小
1 数组类型可以是四种内置类型,也可以是type自定义
2 数组大小只能用正整数常数来赋值
3 访问元素用()圆括号
,不是[]方括号
4 编译不会检查数组是否超过范围,要注意
5 数组下标从1开始
二维数组
语法:
datatype :: name (size1, size2) ! 像一个坐标值
datatype name (size1, size2)
datatype, dimension(size1, size2) :: name
高维数组
Fortran最多可以声明七维数组
注意每个维度的索引值
三个二维数组可以当成三维数组来操作
另类的数组声明
默认数组下标从1开始
特别声明可以改变默认规则:integer a(0: 5) 可以使用 a(0)~ a(5)共6个元素
下标也可以改成负值integer a(-3: 3)
7.2 数组内容设置
赋初值
常规
integer A(5)
DATA A /1, 2, 3, 4, 5/ !可以像一般变量串用DATA赋初值
DATA A /5*3/ ! *表示数据重复,有5个3;可以不用重复同一个数
隐含式(赋初值和输出时都可以使用)
! 单层
integer A(5), I
DATA(A(I), I=2, 4[, 1]) /2, 3, 4/ !省略了DO循环取值,从2~4取值
! 多层
integer A(5, 5), I, J
DATA(((A(I, J), I=1, 2), J=1, 2) /1, 2, 3, 4/ ! 先执行里程再外层
F90可以省略DATA描述
integer :: A(5) =(/ 1, 2, 3, 4, 5 /) ! (/ 之间不可以留空格;必须全部给初值
! 高维还是用data
integer :: b(2, 2)
data b / 5, 6, 7, 8 /
F90隐式
integer :: I
integer :: A(5) =(/ 1, (2, I=2, 4), 5 /) ! (/ 之间不可以留空格;必须全部给初值
! A(5) = (/ 1, 2, 2, 2, 5 /)
integer :: A(5) = (/ (I, I=1, 5) /) ! 给A赋值1~5
一次性赋同一个值
integer :: A(5) =0 ! 5个元素全为0
对整个数组的操作
当a,b,c已经声明
a = 5 ! 全元素设置为5
a = (/ 1, 2, 3 /) !赋初值,左右元素相当
a = b ! a, b同维度大小,将a的元素与b设置相同
a = b + c ! abc同维度大小,bc对应加和给a + - * /四则运算都有
a = sin(b) ! 对应元素取sin,a=f(b)
!!! 特殊用法,搭配WHERE命令
a = b > c
! a, b, c是三个同维度大小的数组,a是逻辑类型,bc是同类型,一维时相当于
do i=1, N
if(b(i) > c(i)) then
a(i) = .true.
else
a(i) = .false.
end do
对部分数组的操作(类似切片)
a (start:end:step) = xxx
a (start:end:step, start:end:step) ! 高维
start, end, step都可以缺省,注意是
前后均闭合的区间
xxx为常数则将对应部分赋值为常数
较低维度是内层循环integer :: a(2, 2) = (/1, 2, 3, 4 /) ! 高维还是用data integer :: a(2, 2) data a /1, 2, 3, 4 / ! a(1, 1) = 1, a(2, 1) = 2, a(1, 2) = 3, a(2, 2) = 4 write(*, *) a ! 可以直接输出数组 write(*, *) a(:, 1) ! 相当于输出a(1, 1), a(1, 2)
write(*, *) a(:, 1) ! 相当于输出a(1, 1), a(1, 2)
注意维度的指标,切片时内循环列
在前,取值时行
在前
WHERE (python借鉴,Fortran95加)
利用逻辑判断
使用数组的部分元素
program main
implicit none
integer :: i
integer :: a(5) = (/(i, i=1, 5)/)
integer :: b(5) = 0
where(a<3) ! 简写 where(a<3) b=a
b=a ! 将a小于3的对应元素赋给b
end where
write(*, "(5(I3, 1X))") b
stop
end
WHERE比DO循环更加精简,执行也更快,尤其并行。
WHERE描述与IF描述有些类似
where是用来设置数组的,只能出现相同大小的数组
还可以与ELSEWHERE
联用,也可以多重判断、嵌套
和DO循环类似也可以署名,END WHERE时也需要加署名
FORALL (Fortran95加)
隐式循环使用数组
forall(i =1:5) ! 等价于a(1:5)=5
a(i)=5
end forall
详细语法:
forall(triple1[, triple2[, ...]], mask)
......
end forall
triple_n代表赋值数组坐标的值,i=start: end: step;数组维度≥triple数目
mask条件判断,与WHERE类似,只处理符合条件的元素,可以多个条件integer :: a(5, 5), I, J ...... forall(I=1:5, J=1:5, a(I, J) < 10 .and. a(I,J)>0) ! 只处理小于10大于0的元素 ...... end forall
FORALL也与IF,WHERE类似,单行可接在后面,省略end FORALL
FORALL可以嵌套,FORALL内部可以使用WHERE(相当于mask),但WHERE内部不可以用FORALL
7.3 数组的保存规则
1.数组不管什么形状,实际在内存中都是连续存储的
一维integer a(5):顺着下标a(1)->a(5)
多维使用“Column Major”的方法,就是先放入Column中的每个Row,第一个Column放完放第二个Column
二维integer a(3->row, 3->column):a(1,1)->a(2,1)->a(3,1)-a(1,2)–>a(3,2)—>a(3,3)
多维情况,先放低维元素(指标最靠前的维度),维越小越使用内层循环integer a(2, 2, 2) ...... do i=1,2 do j=1,2 do k=1,2 write(*,*) a(k,j,i) end do end do end do
针对以上特点可以将同一组使用的数据放在邻近的位置,CPU读取效率会变高
7-4 可变大小的数组
以前:事先声明超大数组来使用部分以达到“可变”大小的数组
Fortran90可以等到执行后动态决定数组大小
示例:
program main
implicit none
integer :: students
integer, allocatable :: a(:) ! a can be changed
integer :: i
write(*, *) "How many students"
read (*, *) students
allocate(a(students)) ! Configure memory space
do i=1, students
write(*, "('Number: ', I3)") i
read (*, *) a(i)
end do
stop
end
声明可变数组时需要加allocatable(可分配)
为了说明声明了数组,a(: ),(:)表示a是一个数组
使用之前还需要allocate(name(size))设置大小,大小的值可以用变量
设置完大小就正常使用
allocate(name(size), stat=error) 检测是否申请成功,error提前设置
deallocate释放allocate申请的内存空间,联合使用这两个命令可以重新设置数组大小
7-5 数组的应用
八、函数
函数是自定义函数和子程序的统称,一般将重复使用的部分独立封装出来
8.1 子程序 SUBROUTINE
CALL
命令调用
语法
program main ! 主程序
...... ! 主程序内容
end program main
subroutine sub1() ! 第一个子程序
...... ! 子程序内容
end subroutine sub1 ! 第一个子程序结束
subroutine sub2() ! 第二个子程序
...... ! 子程序内容
end subroutine sub2 ! 第二个子程序结束
主程序program的调用一开始就会自动执行
子函数必须要主动调用才会执行
主程序名称随意,但子程序名称需固定且适当,一改俱改
主程序不一定要放在代码首部,可以放在任意位置
子程序最后一般会有RETURN命令,即返回主程序最开始调用的部位继续执行
子程序不要出现STOP否则会提前终止所有程序,出现意外
子程序拥有独立地变量声明
Fortran传参是地址传入
,传入的参数仍然需要声明
8.2 自定义函数(FUNCTION)
调用自定义函数需要事先声明
自定义函数执行后会返回一个数值
需要用关键词FUNCTION
来标注定义的是函数
需要在主程序内声明,使用返回类型, external :: 函数名
语法
调用时直接用函数名
即可,不需要用CALL
在函数体内还需要再次声明返回类型
函数可以转化成SUBROUTINE来实现
8.3 全局变量
COMMON声明全局变量
声明变量之后用COMMON关键字来声明变量是全局变量
program main
......
integer :: a, b
common a, b
a = 1
b = 2
......
end
subroutinue Subprogram()
integer :: num1, num2
common num1, num2 ! num1=>a, num2=>b
......
end
全局变量一旦声明之后就不能用DATA命令随意修改初值了
子程序中声明全局变量只是确定主程序全局变量的顺序
,并不是重新申请变量
子程序全局变量根据相对位置来确定,并不是根据名称
全局变量使用一个地址,一经修改就会全局改变
子程序全局变量声明和顺序有关,因此若使用最后一个全局变量需要声明全部,考虑署名分组方法integer :: a, b common /group1/ a common /group2/ b ! in subprogram1 use a: integer :: num1 common /group1/ num1 ! in subprogram2 use b: integer :: num2 common /group2/ num2
传参和全局变量使用建议:
共享变量不多,且只有少数程序使用就传参
共享大量数据,且不修改等时使用全局变量
BLOCK DATA
关于全局变量初值的设置与修改,会在主程序执行前自动执行
分组的全局变量赋值也类似
语法:
block data [name]
implicit none
integer a, b
common a, b
data a, b /1, 2/
end [block data [name]]
全局变量不可以声明为常量PARAMETER
注意事项
COMMON只用来提供一块共享内存,因此要注意变量的类型和位置
一个技巧是子程序使用全局变量可以使用数组来接收
COMMON不是检查类型,一旦修改类型就需要全局一起修改
8.4 函数中的变量
传参可以是变量也可以是一个具体的数字
传递数组参数
数组实际上是一块连续内存空间,传递数组实际上是传入某一个内存地址
传数组名就是传递第一个元素的地址
传递a(2)就是传递a下标为2的地址
传到子函数中后子函数可以根据需要来取传入部分起始之后的部分或全部值
子程序中的数组可以使用变量确定大小甚至不需要给出大小integer :: num(*) ! 不赋值大小
原因在于数组在主函数中已经完全固定
,只要使用时不越界就可
注意:多维数组传递时只有最后一个维度可以不用赋值,其他都必须确定
SAVE增加变量生存周期
子程序加入SAVE声明的变量会保留其一直存在,可以用来记录子程序调用次数
函数也可以作为参数传递
8.5 特殊参数的使用方法
Fortran 90
设置参数的属性:读写权限;不定个数参数;不按顺序传递参数
1.参数属性
语法 | 含义 |
---|---|
intent(in) | 只读 |
intent(out) | 指定为输出结果的参数,类似于返回值返回到参数上 |
intent(inout) | 可读可写,相当于未指定 |
默认 | 可读可写 |
2.函数接口 INTERFACE
一段程序模块,用来清楚说明调用函数的参数类型以及返回值类型
函数返回值为数组
指定参数位置传参
调用函数参数不定
输入为指标参数时
函数返回值为指针
写在主程序中
利用optional关键字表示参数是可选的
integer, optional :: b ! b是可选的
>>>后续用到补充
8.6 特殊函数类型
1.递归 RECURSIVE
函数中的局部变量每次调用函数是必须使用独立地址
由于递归函数会调用自身,因此它的函数名不能作为返回值类型声明
recursive integer function fact(n) result (ans)
! 递归标记 返回类型 函数名 返回值名
2.内部函数 CONTAINS关键字
将函数做一个归属,定义其只能在某些特定函数中被调用,将函数定义在该范围中。
3.PURE函数
配合并行计算使用
要求:
加在FUNCTION/SUNROUTINUE前
参数必须只读INTENT(IN)
子程序参数必须赋值属性
PURE函数中不能用SAVE
包含内部函数只能是PURE
不能有终止,输入输出等
PURE只能读取不能修改全局变量的值
4.ELEMENTAL函数
也可以用来做并行化,除了PURE的限制,还有就是参数不能是数组
主要用来设置数组内容:
program main
.....
integer i
real :: a(10) = (/ i, i=1, 10/)
a = func(a) ! 相对难赋值的情况
.....
end
elemental real function func(num)
implicit none
real, intent(in) :: num
func = sin(num) + cos(num)
return
end function
8.7 MODULE
封装具备相关功能和变量
1.MODULE中的变量
比如将全局变量(SAVE变量)全部声明到MODULE块中,使用时用USE这个MODULE就可
因为全局变量主程序会调用,因此需要将MODULE写到最前面,MODULE中已经声明了全局变量,程序中不需要声明,直接使用
module global
implicit none
integer a, b
common a, b
end module
program main
use global ! 使用MODULE模块
a=1
b=2 ! 直接使用
...
end program
subroutinue sub()
use global
xxx a, b ! 直接使用
......
end subroutinue
2.MODULE中TYPE
将type定义的类型封装,而type可以将多个参数合起来封装后传参等都会简洁
8.8 使用多文件 INCLUDE
将函数写在另一个文件中,include这个文件就可以直接调用文件里的函数
九、文件
计算机的重要功能:1、计算与处理数据 2、读取和保存数据
Fortran语言中读取文件有直接读取和顺序读取顺序读取类似于录音带,要略过数据或者重新读取,需要快转或倒带
直接读取类似于光盘,可以跳跃到文件的任意位置读写文件保存格式分为 文本文件和二进制文件
文本文件就是按照字符存储,直观,但计算机识别需要转换
二进制文件读取速度很快,而且节省空间
9.1 文件操作
1.OPEN
read,write第一个参数之前用的是*,默认键盘和显示器,使用OPEN之后就可以用文件输入输出了
示例:
program main
implicit none
open(unit=10, file='aaa.txt')
! unit=N给后面文件指定一个代码/号 file="xxx"打开的文件名
write(10, *) "Hello world"
! write(unit=10, FMT=*) "Hello world" !严谨写法
stop
end
OPEN(UNIT=num, FILE='filename', FORM='', STATUS=' ', ACCESS=' ', RECL=length, ERR=label, IOSTAT=iostat, BLANK=' ', POSITION=' ', ACTION=action, PAD=' ', DELIM=' '
参数 | 值 | 备注 |
---|---|---|
UNIT | 正整数,文件代码 | 2,6默认输出位置屏幕;1,5默认输入位置键盘;用一个常数固定 |
FILE | 文件名字符串 | Windows不区分大小写,UNIX区分;避开中文 |
FORM | 字符串 | FORMATED(默认 )/UNFORMATED 文本格式/二进制格式 |
STATUS | 声明打开文件 | NEW新文件;OLD已存在;REPLACE:存在会覆盖,否则新建;SCRATCH暂存,不需要指定文件名,程序结束自动删除;UNKNOWN(默认 ):编译器自定义一般同REPLACE |
ACCESS | 读写文件方式 | SEQUENTIAL(默认 )顺序读写;DIRECT直接读写 |
RCEL | 读取大小 | 顺序读取时,设置读取内容的容量 |
ERR | 行代码 | 读取报错会跳转LABEL行 |
IOSTAT | 整数 | 文件打开状态,>0错误;=0正常;<0终了 |
BLANK | NULL/ZERO | 空格代表意义 |
POSITION | ASIS/REWIND/APPEND | 文件打开是的读写位置,ASIS(默认 )开头;REWIND开头;APPEND结尾 |
ACTION | 读写权限 | READ;WRITE;READWRITE(默认 ) |
PAD | 格式化输入空字段处理 | YES(默认 )最前面的不足空格补满;NO所有不足空格补满 |
DELIM | 输出字符串 | NONE纯粹输出;QUOTE加双引号;APOSTROPHE加单引号 |
2.WRITE、READ
参数 | 值 | 备注 |
---|---|---|
ADVANCE | 读写位置是否换行 | YES(默认 )换行;NO不换行。使用前必须指定FMT |
3.查询文件状态INQUIRE(P238)
参数 | 值 | 备注 |
---|---|---|
OPENED | 是否已OPEN | 返回bool值 |
NUMBER | 查看文件给定代码 |
>>> 读取时注意跳过多少字符,读取的数据占几个字符,否则读取会失败
十、函数新学
函数可以传递函数
program func_by_func
implicit none
real, external :: func