Fortran编程快速入门

文章目录

  • 程序的基本结构
  • 输出命令
    • write命令
    • print命令
  • 输入命令
  • 基本数据类型
    • 整型integer
    • 浮点数Real
    • 复数Complex
    • 字符串Character
    • 逻辑型Logical
  • 格式化输入输出
  • implicit命令
  • 常量的声明
  • 等价声明
  • 声明的位置
  • 自定义数据类型
  • 条件判断语句
  • 逻辑运算符
    • Fortran 90的逻辑运算符如下:
    • Fortran 77的逻辑运算符如下:
    • 逻辑表达式示例
    • 逻辑表达式之间的集合运算符:
  • select case语句
  • 其他流程控制
  • do循环
  • do while循环
  • 循环的流程控制
  • 署名的循环
  • 一维数组
  • 二维数组
  • 数组的索引
  • 数组的初始化
  • 数组的存储规则
  • 数组的操作
  • where命令
  • forall命令
  • 大小可变的数组
  • 子程序
  • 自定义函数
  • 全局变量
  • 变量的生命期
  • 传递参数
  • 参数的只读操作
  • 函数的使用接口
  • 不定个数的参数传递
  • 改变参数传递位置的方法
  • 函数递归
  • 内部函数
  • module命令
  • 函数的重载
  • entry命令
  • 自定义操作符
  • 参考

程序的基本结构

程序结构:

program main
......
stop
end

end 语句的三种写法(根据 Fortran 90 标准):

end

end program

end program main

这三种写法在功能上是等效的,可以根据编程习惯或代码规范选择使用。

输出命令

write命令

  1. 基本格式
write(*, *) a

第一个 *:输出位置(默认是屏幕,即标准输出)。

第二个 *:不指定输出格式(自由格式输出)。
  1. 严谨写法
write(6, *) "string"           ! 较严谨写法,6 通常代表屏幕(标准输出)
write(unit=6, fmt=*) "string"   ! 最严谨写法,显式指定 unit 和 fmt

unit=6:通常指屏幕输出(但具体数值可能因系统而异)。

fmt=*:表示自由格式输出。
  1. 注意事项
    自动换行:每次执行 write 后,会自动换行(类似于 println)。

输出双引号:在字符串中输出 " 时,需连用两个双引号 “”。

write(*, *) "This is a ""quoted"" string."  ! 输出:This is a "quoted" string.
  1. 示例
program example
    implicit none
    integer :: a = 10
    write(*, *) "The value of a is:", a  ! 自由格式输出
    write(6, '(A, I3)') "Formatted a:", a  ! 指定格式输出
end program example

关键点总结
write(*, *) 是最简单的写法,适用于快速输出。

write(unit=6, fmt=*) 更严谨,适用于正式代码。

自动换行,若需连续输出不换行,需调整格式或使用 advance='no'(在 Fortran 95+ 支持)。

双引号转义 使用 ""

print命令

  1. 基本格式
print *, a

*:表示不限定输出格式(自由格式输出)。

无括号:print 语句不使用括号,区别于 write。
  1. 特点
    仅支持屏幕输出:

print 只能输出到屏幕(标准输出),不能像 write 那样指定输出位置(如文件)。

  • 相当于 write(*, *) 的简化版。

自动换行:

  • 每次执行 print 后会自动换行(类似于 write)。

格式限制:

  • 不能像 write 那样指定详细格式(如 ‘(A, I3)’),只能使用自由格式 *。
  1. 与 write 的对比
特性 print write
语法 print *, a(无括号) write(*, *) a(带括号)
输出目标 仅屏幕(不能改) 可指定(如屏幕 6 或文件)
格式控制 仅自由格式 * 可自由格式 * 或自定义格式
严谨性 较简单,适合调试 更灵活,适合正式代码
  1. 示例
program example
    implicit none
    integer :: x = 42
    print *, "The value of x is:", x  ! 输出到屏幕,自由格式
end program example

输入命令

基本格式:

read(*,*) a


第一个星号 * 表示输入来源为默认设备(通常是键盘)。

第二个星号 * 表示不指定输入格式,采用自由格式读取。

严谨写法:

read(5,*) a
使用设备号 5(通常代表键盘输入),格式自由。

read(unit=5, fmt=*) a
最严谨的写法,明确指定输入设备(unit=5)和自由格式(fmt=*)。

注意事项:
设备号 5 是传统约定,具体数值可能因编译器或系统而异。
自由格式(*)适合简单输入,复杂数据建议指定明确格式。

基本数据类型

整型integer

  1. 基本整型声明
integer :: a  ! 默认整型,具体字节数取决于编译器(通常为4字节)
  1. 长整型(通常4字节)
Fortran 90 风格(推荐):
integer(kind=4) :: a  ! 明确指定4字节整型

Fortran 77 传统风格:
integer*4 :: b       ! 4字节整型(旧式写法)
integer(4) :: c      ! 4字节整型(旧式写法)
  1. 短整型(通常2字节)
Fortran 90 风格(推荐):
integer(kind=2) :: a  ! 明确指定2字节整型

Fortran 77 传统风格:
integer*2 :: b       ! 2字节整型(旧式写法)
integer(2) :: c      ! 2字节整型(旧式写法)
  1. 注意事项
kind 值(如 kind=4) 取决于编译器,不同系统可能不同。

可移植替代方案:使用 selected_int_kind 函数,如:
integer, parameter :: long = selected_int_kind(9)  ! 至少支持9位十进制数
integer(kind=long) :: big_num

浮点数Real

  1. 基本浮点型声明
标准声明(单精度,通常4字节):
real :: a  ! 默认浮点型(单精度,具体字节数取决于编译器)
  1. 单精度浮点数(通常4字节)
Fortran 90 风格(推荐):
real(kind=4) :: a  ! 明确指定4字节单精度浮点数

Fortran 77 传统风格:
real*4 :: b       ! 4字节单精度浮点数(旧式写法)
real(4) :: c      ! 4字节单精度浮点数(旧式写法)
  1. 双精度浮点数(通常8字节)
Fortran 90 风格(推荐):
real(kind=8) :: a  ! 明确指定8字节双精度浮点数

Fortran 77 传统风格:
real*8 :: b       ! 8字节双精度浮点数(旧式写法)
real(8) :: c      ! 8字节双精度浮点数(旧式写法)
  1. 更高精度的浮点数(如16字节)
Fortran 90 风格:
real(kind=16) :: a  ! 16字节扩展精度浮点数(部分编译器支持)

Fortran 77 风格:
real*16 :: b       ! 16字节扩展精度浮点数(非标准,部分编译器支持)
  1. 注意事项
    kind 值(如 kind=4 或 kind=8) 取决于编译器,不同系统可能不同。

可移植替代方案:使用 selected_real_kind 函数,如:

integer, parameter :: dp = selected_real_kind(15, 307)  ! 至少15位有效数字,指数范围±307
real(kind=dp) :: double_num

复数Complex

  1. 基本复数声明
标准声明(单精度复数,实部和虚部各占4字节):
complex :: z  ! 默认复数类型(单精度,实部和虚部均为 `real` 类型)
  1. 单精度复数(实部+虚部各4字节,共8字节)
Fortran 90 风格(推荐):
complex(kind=4) :: z  ! 单精度复数(实部、虚部均为 `real(4)`)

Fortran 77 传统风格:
complex*4 :: z1       ! 单精度复数(旧式写法)
complex(4) :: z2      ! 单精度复数(旧式写法)
  1. 双精度复数(实部+虚部各8字节,共16字节)
Fortran 90 风格(推荐):
complex(kind=8) :: z  ! 双精度复数(实部、虚部均为 `real(8)`)

Fortran 77 传统风格:
complex*8 :: z1       ! 双精度复数(旧式写法)
complex(8) :: z2      ! 双精度复数(旧式写法)
  1. 复数赋值方式
直接赋值:
complex :: z
z = (1.0, 2.0)  ! 实部=1.0,虚部=2.0(默认单精度)


双精度复数赋值:
complex(kind=8) :: z
z = (1.0d0, 2.0d0)  ! 使用 `d0` 表示双精度常量
  1. 注意事项
    kind 值:
kind=4 对应单精度(real(4)),kind=8 对应双精度(real(8))。

可移植写法建议使用 selected_real_kind 定义 kind:
integer, parameter :: dp = selected_real_kind(15, 307)  ! 双精度
complex(kind=dp) :: z
  1. 复数运算示例
complex(kind=8) :: z1, z2, z_sum
z1 = (1.0d0, 2.0d0)  ! 1 + 2i
z2 = (3.0d0, 4.0d0)  ! 3 + 4i
z_sum = z1 + z2      ! 结果为 (4.0d0, 6.0d0)

字符串Character

  1. 基本字符声明
单字符声明:
character :: ch  ! 声明单个字符(默认长度为1
  1. 字符串声明(固定长度)
Fortran 90 风格(推荐):
character(len=10) :: str  ! 声明长度为10的字符串

Fortran 77 传统风格:
character(10) :: str1     ! 长度为10的字符串
character*10 :: str2      ! 旧式写法
character*(10) :: str3    ! 旧式写法
  1. 字符串赋值
    直接赋值:
character(len=10) :: str
str = "Hello"  ! 赋值后,str为"Hello     "(剩余部分用空格填充)

动态截断或填充:
Fortran 会自动截断超长字符串或用空格填充不足部分。
  1. 字符串操作
子字符串操作:
character(len=10) :: str = "ABCDEFGHIJ"
str(2:5) = "1234"  ! 修改部分内容,结果为"A1234FGHIJ"

字符串连接(使用 // 操作符):
character(len=5) :: s1 = "Hello"
character(len=6) :: s2 = "World!"
character(len=11) :: s3
s3 = s1 // s2  ! 结果为"HelloWorld!"
  1. 注意事项
    长度处理:
    如果赋值字符串比声明长度短,剩余部分用空格填充。
    如果赋值字符串比声明长度长,超出的部分会被截断。
动态长度字符串(Fortran 2003+):
character(len=:), allocatable :: dyn_str  ! 可动态分配长度的字符串
dyn_str = "Flexible length"  ! 自动分配所需长度
program string_example
  implicit none
  character(20) :: string
  
  string = "Good morning."
  write(*,*) string           ! 输出: Good morning.
  
  string(6:) = "evening."
  write(*,*) string           ! 输出: Good evening.
  
  string(3:3) = '!'
  write(*,*) string           ! 输出: Go!d evening.
  
  string(1:2) = '60'
  write(*,*) string           ! 输出: 60!d evening.
  
  stop
end program string_example
  1. 注意事项

子串索引:

  • string(start:end):从 start 到 end 的子串。

  • string(start:):从 start 到字符串末尾。

  • 空格填充:
    Fortran 固定长度字符串始终用空格填充未使用的部分。

  • 错误处理:
    原代码 string([3:1:3]=‘!" 语法错误,应为 string(3:3) = ‘!’。
    字符串赋值需用单引号(’)或双引号(")包裹。

program example              ! 程序开始,名称为 example
  character(20) :: string    ! 声明长度为20的字符串变量 string
  character(30) :: add       ! 声明长度为30的字符串变量 add
  string = "Good morning."   ! 为 string 赋值(13字符,剩余7空格填充):"Good morning.       "7个尾部空格)
  add = string // "Fortran!" ! 连接 string 和 "Fortran!",结果存入 add
  write(*, *) add            ! 输出 add 的内容:"Good morning.       Fortran!  "(尾部补2空格)
  stop                       ! 程序终止
end program example          ! 程序结束
program improved_example
  implicit none
  character(20) :: string = "Good morning."
  character(len=:), allocatable :: add  ! 动态长度
  add = trim(string) // " Fortran!"     ! 精确连接
  write(*, '(a)') 'Result: ', add      ! 格式化输出
end program improved_example

显式修剪空格:

使用 trim 函数移除尾部空格后再连接:
add = trim(string) // " Fortran!"  ! 输出:"Good morning. Fortran!"

Fortran 字符串处理函数总结:

函数名 功能描述 示例
char(num) 返回 ASCII 字符表中数值 num 对应的字符 char(65)'A'
ichar(char) 返回字符 char 对应的 ASCII 码(整数) ichar('A')65
len(string) 返回字符串声明时的固定长度(包括空格) len("Hello ")8(若声明为 character(8)
len_trim(string) 返回字符串去除尾部空格后的实际长度 len_trim("Hello ")5
index(string, key) 返回子串 keystring 中第一次出现的起始位置(未找到则返回 0) index("Fortran", "ran")4
trim(string) 返回去除尾部空格后的字符串(不改变原字符串) trim("Hello ")"Hello"
program string_functions
  implicit none
  character(15) :: s = "  Fortran  "
  
  print *, "char(65): ", char(65)
  print *, "ichar('A'): ", ichar('A')
  print *, "len(s): ", len(s)
  print *, "len_trim(s): ", len_trim(s)
  print *, "index(s, 'ran'): ", index(s, 'ran')
  print *, "trim(s): '", trim(s), "'"
end program string_functions

输出

char(65): A
ichar('A'): 65
len(s): 15
len_trim(s): 8
index(s, 'ran'): 6
trim(s): '  Fortran'
program example
    character(20) :: string       ! 声明长度为20的字符串
    string = "Good morning."      ! 赋值(13字符 + 7空格填充)
    write(*,*) len(string)        ! 输出: 20(声明长度)
    write(*,*) len_trim(string)   ! 输出: 13(实际有效长度)
    stop
end program example
函数 说明 示例输出
len(string) 返回字符串的声明长度(固定值,包含空格) 20
len_trim(string) 返回字符串去除尾部空格后的实际长度 13

逻辑型Logical

  1. 基本声明与赋值
logical :: a, b  ! 声明逻辑变量  
a = .true.       ! 赋值为真  
b = .false.      ! 赋值为假  
  1. 关键特性
    取值:仅有两个值:.true. 和 .false.(注意前后点号)。
    默认值:未初始化的逻辑变量值取决于编译器(通常为 .false.)。

  2. 运算与用途

逻辑运算符:
.and.  .or.  .not.  .eqv.(逻辑等价)  .neqv.(逻辑不等价)  
  1. 示例
if (a .and. .not. b) then  
    print *, "条件成立"  
end if  
格式控制符 描述
Aw 以w个字符宽来输出字符串
BN 定义文本框中的空位为没有东西,在输入时才需要使用
BZ 定义文本框中的空位代表0,在输入时才需要使用
Dwd 以w个字符宽来输出指数类型的浮点数,小数部分占d个字符宽
Ewd[Ee] 以w个字符宽来输出指数类型的浮点数,小数部分占d个字符宽,指数部分占e个字符
ENwd[Ee] 以指数类型来输出浮点数
ESwd[Ee] 以指数类型来输出浮点数
Fwd 以w个字符宽来输出浮点数,小数部分占d个字符宽
Gwd[Ee] 以w个字符宽来输出任何种类的数据
Iw[m] 以w个字符宽来输出整数,最少输出m个数字
Lw 以w个字符宽来输出T或F的真假值
nX 在输出的位置前添加n个空格
/ 换行
: 在没有更多数据时结束输出
kP k值控制输入输出的scale
Tn 输出的位置移动到本行的第n列
TLn 输出的位置向左相对移动n列
TRn 输出的位置向右相对移动n列
SP 在数值为正时加上“正号”
SS 取消SP

以下是Fortran 90添加的格式:

格式控制符 描述
Bw[m] 把整数转换成二进制来输出,输出会占w个字符宽,m值可以不给定
Ow[m] 把整数转换成八进制来输出,输出会占w个字符宽,m值可以不给定
Zw[m] 把整数转换成十六进制来输出,输出会占w个字符宽,m值可以不给定

格式化输入输出

program example
    integer :: a = 20
    write(*,"(I4)") a   ! 格式化输出:"  20"
    write(*,*) a        ! 自由格式输出:"20"
end program example

格式字符串需用双引号包裹:“(I4)”
等效于独立的 format(I4) 语句,但更简洁
字母 I 表示整型,4 控制输出宽度

格式化输出:需要对齐数据时(如生成表格)
write(*,"('Value=',I4)") a  ! 输出:"Value=  20"

调试输出:快速查看变量值
write(*,*) "Debug:", a       ! 输出:"Debug: 20"


I:整型(如 I5)
F:浮点型(如 F8.2)
A:字符型(如 A10)
嵌入式格式中,多个变量需用逗号分隔:
write(*,"(I4,F6.2)") num, value
program example
    integer :: a = 20, b = 10
    write(*,"(4I4)") a,b    ! 输出:"  20  10"(使用前两个I4)
    write(*,"(I4,I4)") a,b  ! 输出:"  20  10"
    write(*,*) a            ! 输出:"20"
end program example
代码行 格式说明 输出结果
write(*,"(4I4)") a,b 4I4表示连续4次I4格式(只使用前2次) " 20 10"
write(*,"(I4,I4)") a,b 显式指定两个I4格式 " 20 10"
write(*,*) a 自由格式输出 “20”

implicit命令

  1. 默认规则(历史遗留特性)

Fortran 允许变量不声明直接使用,其类型由变量名的首字母自动决定:

整型变量:首字母为 I, J, K, L, M, N(记忆口诀:I Just Know Lots More Numbers)
iCount = 10    ! 自动视为整型(无需声明)

浮点型变量:其他首字母(如 A, B, X, Y)
average = 3.14  ! 自动视为浮点型
  1. 隐式类型的问题
    代码可读性差:未声明的变量难以追踪类型。
    潜在错误:拼写错误会隐式创建新变量(如误写 tolal 代替 total 不会被编译器报错)。
    维护困难:团队协作时易引发类型不一致问题。

  2. 使用 implicit 自定义规则

可显式指定某些首字母的默认类型(但仍不推荐):
implicit integer (A-D)   ! A/B/C/D 开头的变量为整型
implicit real (X-Z)      ! X/Y/Z 开头的变量为浮点型
program bad_example
  implicit integer (A-C)
  amount = 10    ! 自动为整型(因为A开头)
  count = 3.14   ! 仍为整型(C开头),3.14被截断为3!
end program
  1. 强制显式声明:implicit none
    最佳实践:在程序开头添加 implicit none,强制所有变量必须显式声明。
program good_example
  implicit none  ! 禁用隐式类型
  integer :: i    ! 必须显式声明
  real :: x
  i = 10         ! 合法
  x = 3.14       ! 合法
  ! total = 5.0  ! 编译错误:未声明变量total
end program

常量的声明

  1. 常量的基本概念
    不可变性:常量(Constant)是程序运行期间值固定不变的量,一旦定义后不能修改。
    用途:用于定义数学常数(如π)、物理常数或固定配置参数。

  2. 定义常量的两种语法

(1) 现代风格(Fortran 90+ 推荐)
real, parameter :: pi = 3.1415926  ! 显式声明类型并初始化



(2) 传统风格(Fortran 77)
real pi
parameter(pi = 3.1415926)          ! 分开声明和赋值
  1. 常量命名规则
    遵循变量命名规则(字母开头,可包含数字和下划线)。
    通常使用全大写或首字母大写以区分变量(如 PI 或 MaxIter)。

  2. 常量类型扩展
    常量支持所有基本数据类型:

integer, parameter :: MAX_STEPS = 1000      ! 整型常量
real, parameter :: GRAVITY = 9.81          ! 浮点型常量
character(len=*), parameter :: NAME = "Fortran"  ! 字符串常量
logical, parameter :: DEBUG_MODE = .true.  ! 逻辑型常量

等价声明

  1. 基本功能
    EQUIVALENCE 用于强制多个变量共享同一内存空间,修改其中一个变量会直接影响另一个。
real :: a, b
equivalence(a, b)  ! a和b指向同一内存地址
  1. 典型用途
    内存优化:减少重复存储(谨慎使用,现代代码中罕见)。
    数据类型转换:通过共享内存实现不同类型数据的二进制解释。
integer :: int_val
real :: float_val
equivalence(int_val, float_val)  ! 允许通过int_val修改float_val的二进制表示
  1. 使用示例
program equiv_example
  real :: x, y
  equivalence(x, y)
  
  x = 3.14
  print *, y  ! 输出3.14(y与x共享内存)
  
  y = 2.71
  print *, x  ! 输出2.71
end program
  1. 注意事项
    类型安全风险:不同类型变量共享内存可能导致未定义行为。
integer :: i
real :: x
equivalence(i, x)  ! 危险:修改i会破坏x的浮点表示

数组对齐:可用于数组部分重叠(需确保内存对齐正确)。

real :: arr1(10), arr2(5)
equivalence(arr1(6), arr2(1))  ! arr2共享arr1的第6-10元素

声明的位置

program example
    integer :: a = 20      ! 声明整型变量a并初始化为20
    write(*,*) a           ! 输出: 20
    
    integer :: b = [0]     ! 使用方括号初始化(Fortran 2003+特性)
    write(*,*) b           ! 输出: 0
end program example
语法 说明
integer :: a = 20 标准初始化方式,兼容所有 Fortran 版本
integer :: b = [0] Fortran 2003 引入的数组构造器风格初始化,适用于标量或数组初始化

自定义数据类型

program example
    implicit none  ! 强制显式声明变量

    ! 定义派生类型 person
    type :: person
        character(len=10) :: name     ! 姓名(10字符)
        integer :: age                ! 年龄
        real :: height               ! 身高(注意原代码拼写错误为hight)
        real :: weight               ! 体重
        character(len=50) :: address ! 地址(50字符)
    end type person

    ! 声明 person 类型变量
    type(person) :: a, b

    ! 初始化方法1:整体构造
    a = person("Peter", 20, 170.0, 60.0, "China")

    ! 初始化方法2:逐成员赋值
    b%name = "Fortran"  ! 其他成员未初始化(默认值)

    ! 输出
    write(*,*) a        ! 输出 a 的所有成员
    write(*,*) b%name   ! 仅输出 b 的 name 成员
end program

可在类型定义中设置默认值:

type :: person
    character(len=10) :: name = "Unknown"
    integer :: age = 0
    ! ... 其他成员
end type

显式初始化所有成员:

b = person(name="Fortran", age=0, height=0.0, weight=0.0, address="") 

使用命名关联(提高可读性):

a = person(name="Peter", age=20, height=170.0, weight=60.0, address="China")

派生类型数组:

type(person) :: people(3)
people(1) = person("Alice", 25, 165.0, 55.0, "USA")

条件判断语句

program example
    implicit none          ! 强制显式变量声明
    integer :: a = 1       ! 初始化变量a
    
    if (a > 2) then       ! 条件判断:a是否大于2write(*,*) "a>2"  ! 条件成立时执行
    end if
    
end program example
program example
    implicit none          ! 强制显式变量声明
    integer :: a = 1       ! 初始化变量a
    
    if (a > 2) then       ! 条件判断
        write(*,*) "a>2"  ! 条件成立时执行
    else
        write(*,*) "a<=2" ! 条件不成立时执行
    end if
    
end program example
program example
    implicit none
    integer :: a = 1
    
    if (a > 2) then
        write(*,*) "a>2"
    else if (a == 2) then
        write(*,*) "a=2"
    else if (a < 2) then
        write(*,*) "a<2"
    else
        write(*,*) "---"  ! 兜底分支(此处不会执行)
    end if
end program

逻辑运算符

Fortran 90的逻辑运算符如下:

运算符 含义
== 等于
/= 不等于
> 大于
>= 大于或等于
< 小于
<= 小于或等于

Fortran 77的逻辑运算符如下:

运算符 含义
.EQ. 等于(Equivalent)
.NE. 不等于(Not Equivalent)
.GT. 大于(Greater Than)
.GE. 大于或等于(Greater or Equivalent)
.LT. 小于(Little Than)
.LE. 小于或等于(Little or Equivalent)

逻辑表达式示例

当我们要表示一个变量大于1小于3时,有以下示例:

  • if (1 ! 错误
  • if (x>1 .and. x<3) then ! 正确

逻辑表达式之间的集合运算符:

运算符 含义
.and. 逻辑与,如果两边的表达式都成立,则返回“真”
.or. 逻辑或,两边的表达式只要有一个成立,则返回“真”
.not. 逻辑反向,两边的表达式都不成立,则返回“真”
.eqv. 两边表达式的逻辑运算结果相同时,则返回“真”
.neqv. 两边表达式的逻辑运算结果不同时,则返回“真”

select case语句

Fortran编程快速入门_第1张图片

case default是可选的,并不一定要出现在代码中。
case(1:5)代表在这两个数字范围内的所有数值,case括号内还可以用逗号来放入多个数值。
使用selectcase来代替if-elseif的多重分支语句,可以使代码看起来更加简洁,但是也有如下的一些限制:

  • (1)只能使用整型(integer)、字符型(character)、以及逻辑变量(logical),不能使用浮点型与复数。
  • (2)每个case中所使用的数值必须是固定的常量,不能使用变量。
program example
    implicit none
    integer :: a = 4
    
    select case(a)       ! 选择变量a
        case(1)         ! a==1时执行
            write(*,*) "This is 1"
        case(2)         ! a==2时执行
            write(*,*) "This is 2"
        case(3)         ! a==3时执行
            write(*,*) "This is 3"
        case(4,5)      ! a==45时执行(多值匹配)
            write(*,*) "This is 4 or 5"
        case default   ! 默认分支(可选)
            write(*,*) "Unknown"
    end select
end program

其他流程控制

1.goto命令
goto命令提供给程序员一个任意跳跃到程序任意一行代码的能力,被跳过的代码则不会被执行。虽然这在某种情况下很方便,但是会影响代码的可读性,所以不太建议在程序中使用。

2.pause命令
程序执行到pause时,会暂停执行,直到用户按下Enter键才会继续执行。这可以应
用在当屏幕上要连续输出大量数据时,在适当的位置暂停程序,以便用户更好的阅读输出的内容。

3.continue命令
continue命令没有什么实际的用途,它的功能就只是“继续向下执行程序”。

4.stop命令
终止程序。

do循环

Fortran编程快速入门_第2张图片
counter是“计数器”,counter=1表示初始值为1,counter在使用之前需要先进行声明。
lines是计数器的终止数值,counter<=lines时会执行循环语句。
最后面的数值1代表counter变量的增量,I每执行一次循环,counter就加1。
do循环中,计数器的初值、循环终止值、以及循环增量值都可以用常量或者变量来指定。

program example
    implicit none
    integer :: a
    
    do a = 1, 10, 1   ! 循环:a从110,步长1
        write(*,*) a   ! 输出当前a值
    end do
end program

do while循环

在循环次数未知但是循环条件已知的情况下,可以使用dowhile循环。

Fortran编程快速入门_第3张图片

循环的流程控制

  1. cycle命令
    cycle命令可以跳出本次循环,进行下一次的循环,相当于C++中的continue。

  2. exit命令
    exit命令可以跳出当前循环,如果是循环嵌套的情况,则跳出的是exit语句所
    在的循环,而外层循环不会被其影响,相当于C++中的break。

program example
    implicit none
    integer :: a, b
    
    do a = 1, 4       ! 外层循环(a从14do b = 1, 5    ! 内层循环(b从15if (b == 3) then
                write(*,*) "我跳出本次循环了!"
                cycle   ! 跳过本次内层循环
            end if
            write(*,"(2(A4,I3))") "a=", a, "b=", b
        end do
    end do
end program

署名的循环

循环还可以取“名字”,这个用途可以在编写循环时,能明白enddo这个描述的位置是否正确,尤其是嵌套循环中。署名的循环也可以配合cycle和exit来使用。

program example
    implicit none
    integer :: a, b
    
loop1: do a = 1, 10      ! 外层循环(标签loop1)
    loop2: do b = 1, 5    ! 内层循环(标签loop2)
        write(*,*) "This is a test!"
    end do loop2          ! 显式标记内层循环结束
end do loop1              ! 显式标记外层循环结束
end program

一维数组

一维数组的声明格式(最简单的一种):数据类型数组名(数组大小)
例如:

integer arr(10)

在声明数组时,数组大小只能使用常数来指定,常数包括直接填入数字或者使用parameter修饰后的常量。

数组除了可以使用5种基本数据类型之外,还可以使用自定义数据类型。

二维数组

二维数组的声明格式(最简单的一种):
数据类型数组名(sizel,size2)

例如:

integer arr(2,3)

数组的索引

与其他程序语言不同,Fortran中数组的索引值都是从i开始,但是可以经过特别声明的方法来改变这个默认的规则,在声明时,可以特别赋值数组的坐标值使用范围,例如:
integer a(0:5)

上面的例子把数组的索引值设置为从0到5。除了一维数组之外,二维数组也可以使用这种方式来声明数组的索引值。

数组的初始化

Fortran 一维数组初始化方法总结

program array_init
    implicit none
    ! 方法1: DATA语句
    integer :: a(5)
    data a /1,2,3,4,5/
    
    ! 方法2: 直接初始化
    integer :: b(5) = (/10,20,30,40,50/)
    
    ! 方法3: 现代数组构造器
    integer :: c(5) = [5,10,15,20,25]
    
    ! 方法4: 隐含DO循环(需先声明i)
    integer :: d(5), i
    data (d(i), i=2,5) /2,3,4,5/  ! d(1)未初始化
    
    print *, 'a:', a
    print *, 'b:', b
    print *, 'c:', c
    print *, 'd:', d  ! d(1)可能为随机值
end program

基础初始化方式

| 方法         | 语法示例                           | 说明                     | 特点                                   |
| ------------ | ---------------------------------- | ------------------------ | -------------------------------------- |
| DATA语句     | `data a /1,2,3,4,5/`                | 传统Fortran初始化        | 需单独声明和初始化                     |
| 重复值       | `data a /5*3/`                     | 快速填充相同值           | 5个元素均为3                            |
| 直接初始化   | `integer :: a(5) = (/1,2,3,4,5/)`  | 现代Fortran风格          | 声明时初始化,注意(//)无空格          |

现代初始化扩展(Fortran 90+)

| 方法         | 语法示例                           | 说明                     | 特点                                   |
| ------------ | ---------------------------------- | ------------------------ | -------------------------------------- |
| DATA语句     | `data a /1,2,3,4,5/`                | 传统Fortran初始化        | 需单独声明和初始化                     |
| 重复值       | `data a /5*3/`                     | 快速填充相同值           | 5个元素均为3                            |
| 直接初始化   | `integer :: a(5) = (/1,2,3,4,5/)`  | 现代Fortran风格          | 声明时初始化,注意(//)无空格          |

Fortran 隐含循环(Implied DO Loop)总结

隐含循环是 Fortran 中一种无需显式 do-end do 结构的循环语法,主要用于:

  • 数组初始化
  • 输入/输出控制
  • 数组构造器

核心语法

(array_expr, index = start, end [, step])

index:循环变量
start/end:循环范围
step:步长(默认1

典型应用场景

 数组输出控制
integer :: a(5) = [1, 3, 5, 7, 9]
write(*,*) (a(i), i=2, 5)    ! 输出:3 5 7 9
write(*,*) (a(i), i=1, 5, 2) ! 输出:1 5 9(步长2)

数组初始化
integer :: b(5)
data (b(i), i=1,5) /1,2,3,4,5/  ! 传统方法
integer :: c(5) = [(i**2, i=1,5)] ! 现代方法:1,4,9,16,25

多维数组操作
integer :: mat(3,3)
write(*,*) ((mat(i,j), j=1,3), i=1,3)  ! 按行展开输出
program implied_loop_demo
    implicit none
    integer :: i, a(6) = [10,20,30,40,50,60]
    
    ! 输出偶数索引元素
    write(*,*) "Even indices:", (a(i), i=2,6,2)  ! 20 40 60
    
    ! 生成平方数数组
    integer :: squares(5) = [(i**2, i=1,5)]
    write(*,*) "Squares:", squares  ! 1 4 9 16 25
    
    ! 嵌套隐含循环(3x3矩阵)
    write(*,*) "Matrix:", ((i+j, j=1,3), i=1,3)  ! 2,3,4,3,4,5,4,5,6
end program

Fortran 多维数组初始化与隐含循环总结

  1. 多维数组初始化方法
(1) DATA语句 + 嵌套隐含循环(传统方式)
integer a(2,2), i, j
data ((a(i,j), i=1,2), j=1,2) /1,2,3,4/

内存顺序:列优先(Column-major)
a(1,1)=1, a(2,1)=2
a(1,2)=3, a(2,2)=4

(2) 直接初始化(现代方式)
integer :: a(2,2) = reshape([1,2,3,4], [2,2])
明确维度:使用reshape函数控制布局

  1. 数组构造器中的隐含循环
(1) 部分元素重复赋值
integer :: a(5) = (/1, (2, i=2,4), 5/)  ! a=[1,2,2,2,5]

(2) 序列生成
integer :: a(5) = (/1, (i, i=2,4), 5/)  ! a=[1,2,3,4,5]

数组的存储规则

数组的操作

where命令

forall命令

大小可变的数组

子程序

自定义函数

全局变量

变量的生命期

传递参数

参数的只读操作

函数的使用接口

不定个数的参数传递

改变参数传递位置的方法

函数递归

内部函数

module命令

函数的重载

entry命令

自定义操作符

参考

  • Fortran编程快速入门

你可能感兴趣的:(传统与AI编译器,前端)