Fortran 程序设计基础
目录
字符集
字符集:指编写 Fortran 程序时,所能使用的所有字符及符号
字符集类型 | 说明 |
---|---|
英文 26 个字母 | A-Z 及 a-z |
数字 | 0-9 |
22 个特殊符号 | :=+-*/(),.'!"%&;<>?$_ (空格) |
Fortran 不区分命令中字母的大小写,命令中的所有大写英文字母都会被视同为小写字母。INTEGER, integer, Integer, InteGer, INTEGEr 都是同一个命令
C/C++ 是区分大小写的编程语言,在 C 程序中调用 Fortran 或在 Fortran 中调用 C 时,需要注意大小写问题
书面格式
书面格式:指 Fortran 程序代码的编写格式,包括固定格式(Fixed Format)和自由格式(Free Format)
书面格式 | 程序文件名 | Fortran 标准 |
---|---|---|
固定格式 | _.f; _.F; _.for; _.FOR | Fortran 77 |
自由格式 | _.f90; _.F90; _.f95; _.F95 | Fortran 90/95 |
编译器根据程序文件名的后缀,自动确定改文件的编写格式
固定格式
- 每行最多 72 个字符,每一行中,前 6 个字段为非执行字段,第 7-72 个字符是可以用来编写程序的字段
字符位置 | 说明 |
---|---|
第 1 个字符 | 如果是字母 C、c 或星号 *,这一行文本会被当成说明批注,不会被编译 |
第 1-5 个字符 | 如果是数字,则是用来给这一行程序代码取个代号。不然只能是空格 |
第 6 个字符 | 如果是 “0” 以外的任何字符,则是续行符,表示这一行会接续上一行 |
第 7-72 个字符 | Fortran 程序代码的编写区域 |
第 73 个字符及之后 | 不使用,编译时被忽略,可能导致编译错误信息 |
- 感叹号 “!” 以后的字符会被当做注解
vi 编辑器可提示不符合固定格式
自由格式
- 非常自由的编写格式,没有规定每一行的第几个字符有什么作用
- 注意事项:
- 感叹号 “!” 后的文本都是注解
- 每行可以编辑 132 个字符
- Intel 编译器支持每行无限字符数而 gfortran 仅支持 132 字符数。建议按照 gfortran 标准编写程序
- 代号放在每行最前面,代号由不超过 5 个数字组成
- 续行符为 “&”:当前行要接续下一行时,当前行最后一个字符需要是 “&”;“&” 不能是一行的第一个字符
数据类型声明
整数 (integer) 类型
- Fortran 支持多种位宽的整数类型,位宽包括 1 字节(8 个 bit)、2 字节、 4 字节、8 字节,不同位宽对应着不同的数值范围。
- 例如:4 字节位宽对应的数值范围为 -2147483648~2147483647,约-2^32~2^32
整数位宽 | Fortran 声明方式 | C/C++ 声明方式 |
---|---|---|
1 字节 | integer*1; integer(kind=1) | char |
2 字节 | integer*2; integer(kind=2) | short |
4 字节 | integer*4; integer(kind=4) | int |
8 字节 | integer*8; integer(kind=8) | long |
- 当采用 integer 声明整数变量时,通常位宽默认为 4 字节,但可通过编译选项改变默认位宽
- GNU 编译器中把 integer 类型声明默认位宽设为 8 字节的编译选项为
-fdefault-integer-8
;GNU 编译器不支持 2 字节位宽,例如:gfortran -fdefault-integer-8
- Intel 编译器中控制 integer 类型声明默认位宽(2、4、8字节)的编译选项:
-i{2|4|8}
设置字节长度,例如:ifort -i8
-integer-size <size>
设置位宽,包括 16、32、64,可设置为 64 位(8 字节)
- GNU 编译器中把 integer 类型声明默认位宽设为 8 字节的编译选项为
- 将整数位宽写成参数形式,位宽参数可以直接赋值或用
selected_int_kind
来设置selected_int_kind(8)
表示 8 位最大的 10 进制数对应的整数类型,实际上是 4 字节整数selected_int_kind(10)
表示 8 字节整数
- 设计整数不同位宽的意义
- 整数位宽应该足够,以避免错误的溢出
- 在位宽足够的情况下,越小的位宽意味着越少的存储空间需求、访存带宽用量和 I/O 带宽用量,意味着更快的计算速度
- 在过去,不同位宽的整数计算的指令开销不同
- GCC (新版)可支持位宽为16字节整数,但 Intel 编译器还不支持
- 大多数处理器指令至多能运算 8 字节整数,16 字节整数只能用程序模拟执行,因此计算速度慢
浮点数 (real) 类型
- Fortran 支持三种位宽的浮点数类型,位宽包括 4 字节、8 字节、16 字节,不同位宽对应着不同的数值范围和有效数位。
精度 | 正数取值范围 | 负数取值范围 |
---|---|---|
单精度类型 | 1.4e-45 至 3.4e+38 | -3.4e+38 至 -1.4e-45 |
双精度类型 | 4.9e-324 至 1.798e+308 | -1.798e+308 至 -4.9e-324 |
浮点数位宽 | Fortran 声明方式 | C/C++ 声明方式 |
---|---|---|
4 字节 | real*4; real(kind=4) | float |
8 字节 | real*8; real(kind=8) | double |
16 字节 | real*16; real(kind=16) | long double |
- 早期编译器版本可能不支持 16 字节浮点数
- 大多数处理器指令至多能运算 8 字节浮点数,16 字节浮点数只能用程序模拟执行,因此计算速度很慢,特别是除法
- 当采用 real 声明整数变量时,通常位宽默认为 4 字节,但可通过编译选项改变默认位宽
- Intel 编译器中设置浮点数默认位宽的编译选项:
-r{8|16}
设置字节数-real-size <size>
设置位宽,包括 32、64、128,可设置为 128 位(16 字节)-autodouble
设置为 64 位(8 字节)
- GNU 编译器中设置浮点数默认位宽的编译选项为
-fdefault-real-8
,单精度浮点数默认位宽为 4 字节,双精度浮点数默认位宽为 8 字节,16 字节浮点数在旧版本不支持,新版本支持
- Intel 编译器中设置浮点数默认位宽的编译选项:
逻辑 (logical) 类型
- Fortran 支持多种位宽的逻辑类型,位宽包括 1 字节、2 字节、4 字节、8 字节,但是逻辑判断只有两种结果:“是”(true)和“否”(false)。
整数位宽 | Fortran 声明方式 | C/C++ 声明方式 |
---|---|---|
1字节 | logical*1;logical(kind=1) | bool |
2字节 | logical*2;logical(kind=2) | |
4字节 | logical*4;logical(kind=4) | |
8字节 | logical*8;logical(kind=8) |
- 当采用 logical 声明变量时,通常位宽默认为 4 字节,但可通过编译选项改变默认位宽,改变方法与整数相同
字符 (character) 类型
- 只记录一个字母、符号时的数据类型称为“字符”,记录一连串的字符时,就称为“字符串”。一个字符占 1 个字节。
Fortran 声明方式 | C/C++ 声明方式 | |
---|---|---|
字符 | character a 未赋值时,通常不能被打印出来 | char a |
字符串 | character(len=10) a 未赋值时的默认字符是空格,字符串中的任意位置都可以是有效字符 | char a[10] 字符串以首个 '\0' 结束,通常必须含有至少一个 '\0' |
- 在 Fortran 中,char(0) 即 '\0' 在打印时被忽略,但会被记录
Fortran
! char1.F90
program main
implicit none
character a
character(len=10) b
b = "ab"//char(0)//"cd"
print *, 'start:',a , b, a, ':end'
以下为编译输出过程
bash
$ gfortran -g char1.f90
(Linux)$ ./a.out
(Windows)$ .\a.exe
start:abcd :end
输出解释:字符 a
初始化时未被赋值,因而未被输出,而 char(0) 被忽略,但会被记录,这体现在长度为 10 字符的字符串 b
最终只有两个空格被输出,两个字符位被 \0 (即 char(0)) 填充
Fortran
! char2.F90
program main
implicit none
character a
character(len=10) b
character(len=1) c
a = ' '
b = "ab\0cd"
print *, 'start:',a , trim(b), , ':end'
trim 命令用于去掉字符串后面的空格
以下为编译输出过程
bash
$ gfortran -g char2.f90
(Linux)$ ./a.out
(Windows)$ .\a.exe
start: ab\0cd :end
输出解释:\0
不会被忽略,而是作为普通字符处理,原因在于 Fortran 没有转义字符,同时与字符 a
相比,c
作为字符串体现,因而其默认会被赋值为空格。
数学表达式
- 用 Fortran 来编写数学表达式的规则和方法都很“直观化”,和在纸上做的四则预算仅有少量差别,按照优先级从低到高顺序如下:
- + 加法 - 减法
- - 乘法 / 除法
- *- 乘幂(两个星号要连续)
- ( ) 括号(表示括号起来的部分优先计算)
- 表达式中乘号不能省略
混合精度计算
- 在计算过程中,按照等号右边操作数的最高精度进行计算,存在浮点操作数时,整数被转化为浮点数进行计算
- 将立即数(即运算式中的常数,与变量相区别)赋值给浮点变量时,可能因为溢出而发生四舍五入
- 在浮点计算过程中,四舍五入发生在等号右边的计算过程
- 浮点数到整数的类型转换过程中,直接舍弃小数位
- C/C++ 也是上述规则
- 浮点立即数默认为real类型,在赋值给双精度变量前可能发生四舍五入计算
- 双精度立即数由最后面的“d0”标记
- C/C++ 没有上述情况