贡献者: addis
&
用于续行,如果一个 token 需要续行,那么下一行的行首也需要 &
. 另外,必须放在注释前面。
program <name> .... end program <name>
, 或者直接用 end
program <name>
可以省略,最后一行 end program <name>
也可以省略
print*, <item1>, <item2>....
星号代表默认格式
read*, item1, item2, ...
来输入变量,要先定义变量类型。
read
读取 character 类型的时候,只能读取字母,不能有任何其他符号
;
符号在一行写多个语句,叫 statement separator. 同一行中的每个 statement 不能超过 132 个字符
stop
可用于终止主程序,return
终止子程序
include "<file>"
就是把文件的内容复制到当前位置,应该相当于 C++ 的 #include
**
== >= <= /=
. 注意不等是用斜杠不是感叹号。感叹号是用于注释的
.and. .or. .not. .eqv.
(同或) .neqv.
(异或)
//
用于连接字符串
if (<logical>) then .... else .... end if
注意要有括号
if (<logical>) then ... else if (<logical>) then ... else ... end if
if
前面可以加上 <name>:
如果这样做, end if 后面也一定要加上 <name>
, 也可以选择在 else if .. then
或 else
后面加上 <name>
. 注意只有开头有冒号,后面没有冒号。
do ii = 1,3; ...; end do;
也可以设置步长 ii = int1, int2, step
. 其中 step
可以是负值。
do while (<logical>) .... end do
exit
相当于 C 语言的 break, exit <name>
用于退出指定循环。
cycle
相当于 C 语言的 continue
<name>:
如果这样,end do
后面也一定要加上 <name>
cycle
执行下一个当前循环,cycle <name>
执行下一个指定循环
do
后面什么都不加相当于无条件循环,需要用 exit
退出。
go to <label>
可以使程序跳转到 <label>
的语句。
integer, real, complex, character, logical
是五种 intrinsic types, 前三种是 numeric, 剩下的是 non-numeric.
implicit none
语句可以使未定义的变量出错。亲自证明了不声明变量类型会导致很严重的错误且很难调试。
implicit double precision (a-h,o-z)
, 作用是默认所有 a-h, o-z 开头的变量都是 double precision, 而 i-n 开头的所有变量都是普通 integer*4
. 这种做法不建议使用。
<类型> :: a=1, b=2, ....
初值可选
::
可以省略
real, parameter :: pi = 3.1415927
parameter (var1 = 1, var2 = 2)
即可。括号不可省略
selected_int_kind(8)
可以返回 integer 类型的 kind, 是的 integer 有 8 位有效数字
selected_real_kind(15, 307)
可以返回 real 类型的 kind, 使得 real 有 15 位有效数字和最大指数 307
huge()
可以测试某个变量的最大值
tiny()
可以测试某个变量的最小值
<类型>(kind=..) :: <name>
的括号中 kind = 可以省略,直接写数字。这个数字叫做 kind type parameter
kind()
函数可以检查某个变量的字节数。
precision()
函数可以检查某个变量的精度(小数位数)
1
和 2
都是整型! 尤其注意 1/2 = 0
而不是 1. 至少要加个小数点 !
123, 'good', 1.7e-6
等。
1.3e8
只有 real(4)
的精度(7 位有效数字,默认), 1.3d8
是 real(8)
的精度(16 位有效数字,即 double), 1.3q8
是 real(16)
的精度(33 位有效数字). d
代表 double, q
代表 quad. 另外也可以用 1.3e8_16
的格式,得到类型 real(16)
与 1.3q8
等效,这么做的好处是可以用一个常数变量(parameter)来指定数据类型,例如 1.3e8_rk
real
的默认是单精度 real(4)
. 双精度 real(8)
需要声明。
real
直接赋值溢出会出错,算符运算结果溢出产生 Infinity
1e-40
. 会产生 warning.
real (var, kind)
integer(kind = <n>)
设置占用的字节,可以取 1, 2, 4, 8 或者 16. 即最大值。默认为
kind = 4
. (huge 约 2E9)
int()
注意不是 integer()
nint()
采用四舍五入进行类型转换,而 int()
采用向下取整
3_4
是 kind = 4
的整数 3.
(实部, 虚部)
. 赋值时如果需要包含变量,用强制类型转换 cmplx (Re, Im, 8)
其中 kind = 8
是 double complex
.true.
或 .false.
logical (var, kind)
character (len = <n>)
其中 n
是最大长度,可以等于任意正整数,默认为 1. len =
可以省略
character
不是一个数组,是一个独立的变量,所以不能只改变其中一个元素。声明数组:character(5) :: char(3,3)
生成 3*3 的矩阵,每个矩阵元是 len=5
.
str(n:m)
获取 character 类型变量 str 的第 n 到第 m 个字符,注意不能用 str(n)
用而是用 str(n:n)
str(1,2)(n:m)
获取 character 矩阵的(1,2)元的第 n 到第 m 个字符
str = 'some caracters'
用于赋值(用双引号也行), 字符串左对齐,剩下的位置补 null
(ascii 的 0), 如果长度超出,多出的部分被截去,且不会报错。
str = str1(n:m)
同样是左对齐,但是后面补空格
iachar()
,如 iachar(str(1,2)(3:3))
. 如果输入的变量有多于一个字符,返回首字符的 ascii 代码
//
可以链接两个字符变量,然后把所有的 null 变为空格
trim()
可以把字符变量最后的空格或者 null 去掉并返回 len 较短的字符常量
len()
可以用于返回字符变量/常量的长度,如 len('1234 ')
返回 5, len(trim('1234 '))
返回 4
write(var, *) var1, var2, ...
可以像输出到命令行一样将字符串或变量写到 character 变量中
integer, dimension (5,5) :: mymatrix
integer :: matrix(5,5) 或者 integer matrix(5,5)
integer :: matrix(-3:1, 0:4)
. 这样 matrix(-3,0)
等表达都是合法的
a:b
中 a <= b, 否则返回空矩阵(某些维度的长度为 0)
real, allocatable :: Mat (:,:)
allocate ( Mat1 (size1, size2), Mat2 (size1, size2))
.
deallocate (Mat)
养成好习惯,务必写上。
implicit none
, 也需要 allocate
allocate
以后,所有元素都是 0.
rank()
相当于 Matlab 的 ndims, 返回一个 integer
size()
相当于 Matlab 的 numel. 但是 size(Mat, dim)
相当于 Matlab 的 size
shape()
相当于 Matlab 的 size, 返回一个 integer(2)
数组。
lbound(Mat)
返回在每个维度 index 的最小值,lbound (Mat, dim)
返回指定维度的最小值
matrix(1:2,3:4) = 1
a((/1,3,4/))
也是合法的
print
矩阵,会把所有列展开成一行。
n1 : n2 : step
的格式叫做 subscript triplet
(/1,2,3,4/)
相当于 Matlab 里面的中括号,但只能表达一维矩阵。例程 a(1:4,2) = (/1,2,3,4/)
. 里面可以是变量。
logical :: Barray(4) = (/1,1,0,1/)
,
或者 (/.true.,.true.,.false.,.true./)
reshape
可以指定高维度矩阵的赋值:
reshape ( (/5,9,6,10,8,12/), (/3,2/) )
, 生成 3 行 2 列的数组,排序方式和 Matlab 相同
reshape ( array, shape, pad, order )
可以按照矢量 order 指定的顺序来填充矩阵,默认
(/ ( (ii**2+3), ii=0,N ) /)
. 可以在后面加上 *2 之类的。这种格式中 N 不能超过 1e5. 否则只能用循环。
sum (array, dim, mask)
所有元素求和
product (array, dim, mask)
所有元素求积
dot_product(v1, v2)
矢量点乘(仅限于一维矢量)
matmul(mat1, mat2)
矩阵乘法
maxval(array, dim, mask)
矩阵的最大值(不知道 mask 是干啥的)
minval
矩阵的最小值
maxloc(Mat, mask)
找到矩阵中最大元素的位置
minloc(Mat, mask)
找到矩阵中最小元素的位置
transpose()
求转置矩阵
all (logical, dim)
判断逻辑矩阵是否都是 .true. dim 可选
any (logical, dim)
判断逻辑矩阵是否有任何 .true.
count (logical, dim)
>, <, /=
等算符用于两个矩阵返回逻辑数组。进而使用 .and. .or.
等
where ( a < 0 ); a = 1; elsewhere; a = 5; endwhere
pack(Mat, mask)
把 Mat 中对应 mask 中为 .true.
的矩阵元按顺序装到 rank1 向量。如果被赋值的矢量有多余元素,则随机赋值。这相当于 Matlab 中的 Mat (mask)
v = pack(Mat, mask, vector)
多余元素赋值为 vector 中的对应元素。vector 要和 v 的长度一致。
pack(M,.true.)
相当于 Matlab 中的 M(:)
unpack(vector, mask, array)
是 pack 的逆过程
spread(Mat, dim, ncopies)
把 Mat 在 dim 的维度排列 ncopies 次。dim 只能从 1 到 rank(Mat) +1
merge(MatTrue, MatFalse, mask)
在两个矩阵中选取矩阵元组成新的矩阵。mask 是逻辑数组,用于选择矩阵元。
cshift(Mat, shift, dim)
是 circle shift, 把矩阵沿着 dim 的维度循环移动,shift > 0 是向 ind 变小的方向移动。
eoshift()
非循环移动,规则类似。
common/group/var1, var2, ...
其中 var1, var2
的变量名在不同的声明中可以不一致,但是 group 的名字要一样
common/grou/var1(N1), var2(N2)
变量要在 common 之前再定义一次
print (<格式>), item1, item2, item3...
print *, item1, item2...
read (*,*) item1, item2...
write (*,*) item1, item2...
星号代表默认,print
的星号可以替换成 <format>
, read 和 write 的第一个星号可替换成输入输出的位置代号(默认是命令行), 第二个星号可替换成 <format>
write (var, <format>)
可以将内容写到变量中(不确定是否只支持字符串变量)
<format>
可以是一个数字,如 1010
, 这样,必定有另一行指令 1010 format(...)
write(6, 901) a, b, c
901 format(1X,I3/'X=',T7,F5.2/D8.2)
这两个命令相当于在命令行中输出 1 个空格,一个整型(a), 下一行,'X=', tab 到第 7 列,一个 real (b), 下一行,一个 real (c).
print <format>
相当于 write(*,<format>)
<format>
是一个指定输出格式的字符串,例如 '(10ES12.3)'
, '(5I6)'
等。
<format>
字符串的定义
****
<列数>F<列宽>.<小数位数>
<列数>ES<列宽>.<小数位数>
, 显示出来的位数为 <小数位数>+6
所以 <列宽>
需大于等于 <小数位数> +7
(正数+6, 负数带负号+7)
/
表示空白行
<列数>I<列宽>.<显示位数>
对于 <显示位数>
, 不够的前面用 0 补齐,超出的不
处理)
'(<fmt1>, <fmt2>...)'
(我猜测 <列数>
在该情况仍然可以使用)
<列数>A<列宽>
open (1, file = 'data1.txt', status = 'new')
do ii = 1,100
write(1,*) x(ii), y(ii)
end do
close (1)
'new'
是创建新文件,若打开已存在文件,替换成 'old'
status = 'unknown'
, 如果文件存在就用存在的文件,不存在就创建新文件
open(unit=7, file='fort.7', form='Unformatted') 这行可以省略!
write(7) array1
write(7) array2
close(unit=7)
两个写入的矩阵尺寸可以不一样!
open(unit=7, file='fort.7', form='Unformatted') 这行可以省略!
read(7) array1
read(7) array2
real
和 imag
兼容数组。
sqrt(), exp(), log10(), abs(), aimag()
取虚部,**
指数,
sin(), cos(), tan(), asin(), acos(), atan(), atan2(), sinh(), cosh(), tanh(), atanh()
real(array, kind), imag(array, kind), iabs(int), sign(), isign(int)
aimag(), dimag(), qimag()
分别适用 kind = 4, 8, 16 的 complex.
amod(), mod(), idim(), dim()
aint()
向下取整,anint()
最近取整,ceiling()
, floor()
, complx(x, y)
生成复数,conjg()
复共轭,dim(x, y)
差值(正数)
index(string,subtring)
返回 substring 在 string 中的位置
len(string)
返回 string 的最大长度
achar()
把 integer 转换成 character
iachar()
把 character 转换成 integer
trim()
把后面的空格清空。应用 trim(char)//trim(char) 会消除中间多余的空格。
stop <5位数/字符串>
可以终止程序,且显示 <5位数/字符串>
external <subprogram-list>
声明一下,这样如果有 intrinsic 的同名子函数,就会覆盖。
logical, intent(out), optional :: fail
present()
检测 optional 变量是否被输入,如 if (present(fail)) then
subroutine <name> ( arg1, arg2 ) .... end subroutine <name>
call <name> (arg1, arg2)
implicit none
, 需要声明变量(包括输入变量).
integer, dimension (5), intent (out) :: arg1, arg2
. 使用 intent(in)
使变量不可修改,intent(out)
在输入时重置 allocatable 矩阵(常数及普通矩阵保持不变). intent(inout) 有输入且可以修改
interface
必须要在定义变量后面其他语句前面
interface
subroutine funName (Mat)
integer, intent (out):: Mat(:, :)
end subroutine funName
(:,:)
声明变量维度,冒号的个数代表维度。
integer, dimension(:, :) :: Mat
或 integer :: Mat(:, :)
等效
function(var1,var2)
implicit none
, 那么应该声明一个与函数名同名的变量,类型是输出变量的类型。
function(var1,var2) return <output>
use <module_name>
. 必须放在 implicit none
之前。
module <name>
<变量声明>
contains
subroutine <name>
...
function <name>
...
interface
...
end module <name>
<变量声明>
中使用 private 声明,则变量只在 module 内部通用。例如
integer, private :: a(5)
 
 
 
 
 
 
 
 
 
 
 
友情链接: 超理论坛 | ©小时科技 保留一切权利