简明Fortran教程
这是一本简明的Fortran教程,其中包含了常见的Fortran 语法。具有C语言基础会使学习更加容易。
关于Fortran
Fortran是一门编译型编程语言,即将源代码编译链接成可执行程序,再去执行。Fortan最大的特点是快。
Fortran有两种格式,固定格式和自由格式。固定格式需要在行首输入特定的字符进行标识,并且每一行的长度有限制。而自由格式不需要在行首进行标识。
虽然现在编译器仍然支持固定格式,但推荐使用自由格式。
安装
建议新手使用带gfortran编译器的Code::Blocks,上手简单。
基础
字符集
符号数量 | 类型 | 值 |
---|---|---|
26 | 大写字母 | A-Z |
26 | 小写字母 | a-z |
10 | 数字 | 0-9 |
1 | 下划线 | |
5 | 运算符 | + - * / ** |
28 | 其他符号 | ( ) . = , ’ $ : ! " % & ; < > ? ~ \ [ ] ` ^ { } |
程序结构
一个自由格式的程序示例如下:
1 |
|
这个Fortran程序,就像所有的Fortan程序那样被分成了三段:
-
声明段。此部分由一组不可执行的语句组成,这些语句定义程序的名称和
程序中引用的变量的数量和类型以及一些编译选项。
-
执行段。此部分由一组可执行的语句组成,这些语句被用来执行特定的任务。
-
结构段。此部分由一个或多个语句组成,该语句停止程序的执行,并告诉编译器程序执行完毕。
数据类型
Fortran是强变量类型的语言。
- 变量类型必须在编译时确定,并且不允许改变。
- 建议显式声明所有变量。
- 如果未显式声明变量,则按照 IN 规则确定类型(ijklmn开头为整型,其他为实型)
- IN 规则是个很讨厌的东西,因此,我们建议在每一个程序单元,使用 Implicit None
- 变量有不同的类型,主要有整型(Integer)、实型(Real)、字符型(Character),还有 Complex 类型(本质上是real)、派生(type)类型(是其他类型的集合)
- 整型无误差、实型有误差。字符型是接近人类的语言
Fortran 标准数据类型:
变量 | 数据类型 |
---|---|
Integer(Kind=??) :: | 整型 |
Real(Kind= ?? ) :: | 实型 / 浮点型 |
Complex(Kind=??) :: | 复数型(两个实型的组合) |
Character(Kind=1,len=??) :: | 字符型 |
Logical(Kind=??) :: | 逻辑型 / 布尔型 |
Type( ?? ) :: | 派生类型(上述类型的组合) |
Kind
数据的Kind属性用以区分不同长度、精度或编码方式的同一种数据类型。Kind 受编译器的影响,具体数值可能会有差异。Kind 对不同的变量类型,表达的意思也不相同。
- 对 Integer ,Kind 值影响整数能表达的最大范围;
- 对 Real 和 Complex, Kind 值影响实数的最大范围和最小精度;
- 对 Character ,Kind 值表示编码。通常为 ASCII 编码;
- 对 Logical , Kind 值表示长度,对逻辑型无影响。
整型(Integer)
Integer 的 Kind,常见 1、2、4、8 等。
Kind | 类型 | 最小值 | 最大值 |
---|---|---|---|
1 | 超短整型 | -(2^7) -128 | 2^7 -1 127 |
2 | 短整型 | -(2^15) -32768 | 2^15-1 32767 |
4 | 整型 长整型 | -(2^31) -2147483648 | 2^31-1 2147483647 |
8 | 超长整型 | -(2^63) -9223372036854775808 | 2^63-1 9223372036854775807 |
对于大多数编译器,Kind 默认是 4,占有 4 个字节。但大多数编译器也允许调整默认Kind值。
并不是所有编译器都允许1、2、4、8的Kind值。某些编译器不支持Kind=8, Kind=1 ,而某些编译器用1、2、3、4 表示。
TODO:gfortran实验
可以用 k = Selected_Int_Kind( i ) 函数来选择能满足要求的Kind。 i 表示需要最大的十进制位数,k 表示返回的能满足范围的最小的Kind值。
1 |
|
整型和整型的计算结果依然是整型!
例如 1/2 = 0 ; 3/2 = 1
但整数和浮点数的计算结果一般是浮点数,例如 1/2.0 =0.5 。
实型/浮点型(Real)
Real 的 Kind,常见 4、8、16 等。
Kind | 类型 | 最大值 | 最小值 |
---|---|---|---|
4 | 实型 | 3.4028235E+38 | 1.1754944E-38 |
8 | 双精度 | 1.7976931E+308 | 2.2250738E-308 |
16 | 四精度 | 1.1897314E+4932 | 3.3621031E-4932 |
对于大多数编译器,Kind 默认是 4,占有 4 个字节。但大多数编译器也允许调整默认Kind值。
并不是所有编译器都允许4、8、16的Kind值。某些编译器不支持Kind=16 ,而某些编译器用1、2、3 表示。
1 |
|
可以用这个函数来选择能满足要求的Kind。r 表示需要最大的十进制位数 , p 表示最小的有效位数。k 表示返回的能满足范围的最小的Kind值。
由于浮点数存在误差,因此我们应该尽量避免以下操作:
-
对浮点数进行相等判断!
1
if ( a == 1.3 ) => if( abs(a-1.3)<1.0e-5 )
-
用浮点数做为数组角标!
1
b = a(2.0) => b = a(2)
-
用浮点数做为循环变量!
1
2Do r = 0.0 , 2.0 , 0.1 => Do i = 0 , 20
r = i / 10.0
在数值计算中,我们应避免误差的放大和积累,因此设计合理、健壮的算法尤为重要。
复数型(Complex )
Complex 的数据类型与 Real 一致。
但需要注意的是:
如果 Kind=8 的 Real 占用 8 字节,则 Kind=8 的 Complex 占有 16 字节。
若使用 Complex(Kind=16) 来定义双精度,但实际上已经是四精度。
Complex 选择Kind,也使用 Selected_Real_Kind 函数。
字符型(Character )
Character 的 Kind,常见只有一种,即 1 表示 ASCII 编码。
也可以使用 Selected_Char_Kind 来选择。
1 |
|
字符串定义时必须有长度,且通常是固定的。
Fortran的字符串没有结束符 \0,所以在字符串操作中,必须注意!
有必要时需实用 trim 去除尾部空格。
可通过内部文件在字符串和整型、实型间相互转化。
1 |
|
字符型允许使用“子字符串”进行索引切片。
1 |
|
灵活运用子字符串可以让很多事情事半功倍。
逻辑型(Logical)
Logical 的 Kind,通常与该编译器支持的 Integer 一致。
变量声明
Fortran数据除了有类型之外,还有一定的属性,比如Kind。他们用定义时的形容词来赋予。
Fortran变量名必须以字母开头,且不能太长。
Fortran声明变量的基本格式:
类型( 属性 ) , 形容词 , 形容词 … :: 变量名(数组外形)= 值 , 变量名2(数组外形)= 值
下面是一些例子:
1 |
|
运算符与表达式
运算符 | 含义 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
** | 乘方 |
在写复合表达式时,应注意运算符的优先级。
关系运算符
逻辑运算符
输入与输出
Write()
1 |
|
Write(*, *)
中第一个星号代表使用默认输出位置,即屏幕,第二个星号代表不特别设置输出格式。
格式化输入输出
1 |
|
控制流
条件分支
IF语句
IF语句常见的简单结构:
1 |
|
或者:
1 |
|
- IF结构中的逻辑表达式的结果必须是一个单值,不能是数组。
- 数组比较ANY, ALL等函数转换
SELECT CASE语句
SELECT CASE语句的结构:
1 |
|
一般情况下,SELECT CASE语句可以与IF语句进行等价转换。
循环
DO循环
DO循环语句的结构如下:
1 |
|
DO WHILE循环
DO WHILE循环语句的结构如下:
1 |
|
循环控制
- CYCLE:忽略本轮循环剩余内容,直接进入下一轮循环。
- EXIT: (用于循环时)忽略循环剩余内容,跳出(指定)循环。
数组
数组的基本使用
数组的定义
1 |
|
数组的操作
数组的索引从1开始。
赋初值
Data赋值
1 |
|
隐式循环
一个隐式循环的例子如下:
1 |
|
对整个矩阵的操作
1 |
|
索引切片
1 |
|
where
forall
可变大小的数组
1 |
|
函数与子程序
子程序(subroutine)
子程序拥有独立的变量声明。
1 |
|
函数(function)
1 |
|
匿名函数
写法简单,但只能在本程序内使用。
1 |
|
文件操作
实例:写入矩阵到txt
1 |
|
标准数学函数
1 |
|