1.3. 控制结构
Fortran 的控制结构包括条件分支和循环。
1.3.1. 条件分支
1.3.1.1. if-else if-else
integer :: score = 85
if (score >= 90) then
write(*, *) "优秀"
else if (score >= 80) then
write(*, *) "良好"
else if (score >= 60) then
write(*, *) "及格"
else
write(*, *) "不及格"
end if
1.3.1.2. 单行 if
! 单行 if(无需 then/end if)
if (x < 0) x = 0
! 逻辑 if(单条语句)
if (flag) call do_something()
1.3.1.3. if 块嵌套
if (condition1) then
if (condition2) then
! 嵌套 if
...
end if
end if
备注
每个 if 必须对应一个 end if。
else if 之间没有空格——连写为 elseif 也可。
1.3.2. select case 语句
integer :: op = 2
select case (op)
case (1)
write(*, *) "新增"
case (2)
write(*, *) "修改"
case (3)
write(*, *) "删除"
case default
write(*, *) "未知操作"
end select
1.3.2.1. select case 的灵活用法
! 范围匹配
select case (score)
case (:59)
grade = "不及格"
case (60:79)
grade = "合格"
case (80:89)
grade = "良好"
case (90:100)
grade = "优秀"
case default
grade = "无效分数"
end select
! 字符匹配
character(1) :: cmd = "Q"
select case (cmd)
case ("N", "n")
call new_file()
case ("O", "o")
call open_file()
case ("Q", "q")
call quit()
end select
1.3.3. 循环结构
1.3.3.1. do 循环
! 基本 do 循环
integer :: i
do i = 1, 10
write(*, *) i
end do
! 输出: 1 2 3 ... 10
! 指定步长
do i = 1, 10, 2
write(*, *) i
end do
! 输出: 1 3 5 7 9
! 递减
do i = 10, 1, -1
write(*, *) i
end do
! 输出: 10 9 ... 1
! 不含循环变量的 do
integer :: n = 0
do
n = n + 1
if (n > 10) exit
end do
1.3.3.2. do while 循环
integer :: i = 1
do while (i <= 5)
write(*, *) i
i = i + 1
end do
1.3.4. 循环控制
! exit: 退出循环(相当于 C 的 break)
do i = 1, 10
if (i == 5) exit
write(*, *) i
end do
! 输出: 1 2 3 4
! cycle: 跳过当前迭代(相当于 C 的 continue)
do i = 1, 10
if (mod(i, 2) == 0) cycle
write(*, *) i
end do
! 输出: 1 3 5 7 9
小心
exit 和 cycle 只影响**当前最内层**循环。
要跳出多层循环,可以使用命名循环(Fortran 95+):
1.3.4.1. 循环命名
outer: do i = 1, 5
inner: do j = 1, 5
if (i * j > 10) exit outer
write(*, *) i, j, i * j
end do inner
end do outer
1.3.5. 数组循环(隐式 do)
! 隐式 do 用于 I/O 和数组构造
integer :: arr(5)
! 读取数组
read(*, *) (arr(i), i = 1, 5)
! 输出数组
write(*, '(5I4)') (arr(i), i = 1, 5)
! 数组构造
arr = (/ (i * 2, i = 1, 5) /) ! arr = [2, 4, 6, 8, 10]
1.3.6. where 结构(数组条件操作)
real :: a(10), b(10)
! 初始化
a = (/ (i * 1.0, i = 1, 10) /)
! where: 对满足条件的数组元素执行操作
where (a > 5.0)
b = a * 2.0
elsewhere
b = a
end where
1.3.7. forall 结构(Fortran 95+)
integer :: mat(10, 10)
! forall: 并行赋值
forall (i = 1:10, j = 1:10)
mat(i, j) = i + j
end forall
! 带条件的 forall
forall (i = 1:10, j = 1:10, i /= j)
mat(i, j) = 0
end forall
备注
forall 在 Fortran 2008 中已被标记为"过时"(deprecated),
建议使用 do concurrent 替代:
integer :: i, j
do concurrent (i = 1:10, j = 1:10, i /= j)
mat(i, j) = 0
end do
1.3.8. 综合示例:数值积分
梯形法求积分
program integrate
implicit none
integer, parameter :: n = 1000
real(8) :: a, b, h, x, sum
integer :: i
a = 0.0_dp ! 积分下限
b = 1.0_dp ! 积分上限
h = (b - a) / n
sum = 0.5_dp * (f(a) + f(b))
do i = 1, n - 1
x = a + i * h
sum = sum + f(x)
end do
sum = sum * h
write(*, '(A, F12.6)') "积分结果: ", sum
contains
real(8) function f(x)
real(8), intent(in) :: x
f = x**2 ! 求 x^2 在 [0,1] 上的积分
end function f
end program integrate