Skip to content

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; _.FORFortran 77
自由格式_.f90; _.F90; _.f95; _.F95Fortran 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 字节)
  • 将整数位宽写成参数形式,位宽参数可以直接赋值或用 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 字节浮点数在旧版本不支持,新版本支持

逻辑 (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++ 没有上述情况

基于 CC BY-NC-SA 4.0 许可发布