Skip to content

Latest commit

 

History

History
89 lines (82 loc) · 3.32 KB

08. 循环语句.md

File metadata and controls

89 lines (82 loc) · 3.32 KB

Fortran中循环语句结构一共有两种,一种是do关键字,这里类似于C/C++中的for循环(更像Python中的for),另外一种是当型循环,通过do while关键字实现。

do

语法结构:

新标准

do i=n,m,k
    循环体
end do

旧标准

do 100 i=n,m,k
    循环体
100 continue

上述语法表述的意思是变量i的值从n遍历到m,遍历步长为k(可省略,默认为1),新标准看起来很直观。旧标准中do后面的100相当于是给它起了一个别名,需要匹配对应的100 continue。这种结构不再建议使用。例子:

1    integer :: n, var(10)
2    do n=1,10
3        var(n) = n
4    end do

上述语句通过do循环将变量var的元素进行了赋值。另外do循环还可以嵌套使用。例如:

1    integer :: n, m, var(5,10)
2    do n=1,10
3        do m=1,5
4            var(m,n)=m*n
5        end do
6    end do

这里利用嵌套do循环对二维数组var的元素进行了初始化。这里需要注意的一点是,Fortran中的数组是列优先的,和MATLAB中的一致,因此数组在循环的过程中最左边的指标放在最后进行循环是有必要的,这样可以避免过多的内存跳转,充分利用CPU中的缓存功能(Cache)。相比较Numpy和C/C++中的数组都是行优先的。

do while

Fortran中当型循环的逻辑结构为:

do while(条件)
   循环体
end do

do while循环是通过判断括号内的条件是否成立来继续执行循环的,条件成立则会继续执行,否则结束循环。例如利用级数法求解满足一定精度的exp(1)的值:

1    real(8) :: pre=1._8, var=1._8
2    integer :: n=1
3    do while(pre>1d-4)  ! 判断精度
4        pre = pre/dfloat(n) ! 下一个级数项
5        var = var + pre
6        n = n + 1
7    end do
8    write(*,*) var

其中dfloat函数可将整数转换为双精度浮点数,这里需要注意的是,给精度浮点数赋值的时候,数值末尾需要加上_8或者d0(d是双精度浮点数的指数部分),这里比较类似于Java,精度不同的变量需要标识。

另外Fortran中也有类似C/C++中的"break"和"continue"的语法。这里分别对应Fortran中的关键字为exit和cycle。分别用于中断循环,或者跳过此次循环,进行下一次循环。例如利用级数法求解cos(1)的值:

1    real(8) :: pre=1._8, var=1._8
2    integer :: n=0
3    do
4        n = n + 1
5        pre =  pre/dfloat(n) ! 下一个级数项
6        if(mod(n,2)/=0) cycle ! 只有偶数项
7        pre = -pre
8        var = var + pre
9        if(abs(pre)<1d-4) exit  ! 判断精度
10   end do
11   write(*,*) var

这里的abs是绝对值函数。do后面什么都没有代表死循环,也可写作do while(.true.)。

最后讲一些不再建议使用的语法规范:上述求解cos(1)的代码用Fortran77的语法可写为:

1    real(8) :: pre=1._8, var=1._8
2    integer :: n=0
3    do 100
4        n = n + 1
5        pre =  pre/dfloat(n)
6        if(mod(n,2)/=0) goto 100
7        pre = -pre
8        var = var + pre
9        if(abs(pre)<1d-4) goto 200
10   100 continue
11   200 continue
12   write(*,*) var

这里我们更能体会到goto的"强大"的功能。尤其是在多层嵌套中它可以很方便的跳出任意一层的循环。