《Fortran 95 程序设计》阅读笔记二

Chapter 5 流程控制与逻辑运算

If 语句

规范的表达式写作:

if (逻辑判断式) then
  ......
else
  ......
end if

如果只有单行命令的话还可以简写为 if (逻辑判断式) write(*,*) "Hello World!"
特别注意在Fortran 90里面关于等于和不等于的判断表达式分别为 ==\=

逻辑判断语句的连接:

连接语句运算规则
.and.交集
.or.并集
.not.逻辑反向,若后面表达式不成立则整个表达式成立
.eqv.两个表达式逻辑结构一致则表达式成立
.neqv.两个表达式逻辑结构不一致则表达式成立

多重判断与嵌套

多重判断的写法为:

if (condition 1) then
  ......
else if (condition 2) then
  ......
else if (condition 3) then
  ......
else if (condition 4) then
  ......
else
  ......
end if

需要注意的是,如果判断满足条件1,则不会再对条件2等进行判断,会直接跳出循环,只会执行第一个满足条件的执行模块。
嵌套的写法为:

if (condition 1) then
  ......
  if (condition 2) then
    ......
  else if (condition 3) then
  ......
  else
  ......
  end if
end if

浮点数及字符的逻辑运算

对于浮点数的逻辑判断应该预留一点误差比如判断 SQRT(3.0)**2-3.0 == 0.0 则很有可能判断为错,则与有效数位的计算方式有关,在实际编程中应该预留一点误差 abs(SQRT(3.0)**2-3.0 - 0.0) < e 其中 e 为常数参数,设置为一个比较小的值。

select case 语句

在Fortran中使用select case语句会有一些限制:

  • 只能用整数,字符及逻辑变量,不能使用浮点数及复数
  • 每个case中所使用的数值必须是固定的常量,不能用变量
select case (variable)
case (num 1)
  ......
case (num 2)
  ......
case default
  ......
end select

GOTO 语句

在Fortran中由于可以对行表明行号,于是也可以使用 goto 语句直接跳到相应的行,但如果没有碰到goto则会按照顺序继续往下。关于ifgoto 有一个联用的技巧,附上示例:

	C = A - B
! 这里如果 C<0 则goto 10,如果C=0 则goto 20,如果C>0 则goto 30
if (C) 10,20,30
10	write(*,*) 'A<B'
	goto 40
20	write(*,*) 'A=B'
	goto 40
30	write(*,*) 'A>B'
	goto 40
40  stop
	end

但是这种奇技淫巧还是不建议使用。

Chapter 6 循环

Do 循环

在Fortran里面Do循环的用法跟一般语言里面的for是一样的

do counter = 1, 10, 2
  ......
end do

这里面counter为计数器,表示从1开始,步长为2,如果有 counter ≤ 10 \text{counter}\leq 10 counter10则进入循环,否则退出循环。最后的步长默认为1,也可以是负数,但如果是负数的话需要额外注意循环的终止条件。用于设置计数器初值、上限及增值的数值可以是变量,不过这些变量的值只会在进入循环前被读取一次,在循环中改变他们并不会对循环发生作用。

Do while 循环

Fortran里面的Do while语句替代的是C语言中的while语句,用法基本一致

do while(逻辑判断)
  ......
end do

循环的流程控制

CYCLE 与 EXIT

cycle 是指跳出本次循环进入下一次循环,总的循环次数并不会改变;exit 则是跳出整个循环结构

署名循环

在Fortran里面可以对循环署名,然后配合 cycle exit等的使用让循环更加方便,可以看一段示例代码:

loop1: do i=1,3
  loop2: do j=1,3
    if ( i==3 ) exit  loop1  ! 跳离loop1循环
    if ( j==2 ) cycle loop2  ! 重做loop2循环
    write(*, "('(',i2,',',i2,')')" ) i, j
  end do loop2
end do loop1

这样的输出结果则是 (1,1) (1,3) (2,1) (2,3) 四组数据

Chapter 7 数组

基本使用

Datatype name(size)
作为数组的一般声明方法,其中Datatype为数组的类型,可以是整数型浮点型也可以是自定义的类型,size 则是数组的大小,需要注意这里必须是整型。再给出几组声明示例:

integer a(10)	! solution 1
integer, dimension(10) :: a	! solution 2
integer a		! 来自于Fortran77 的做法 先声明为整型
dimension a(10)		!solution 3
Type(person) :: a(10)	! 声明自定义数据类型person的数组

二维数组的定义方式与之类似:

integer a(10,10)	! solution 1
integer, dimension(10,10) :: a	! solution 2

进一步可以声明并调用高维数组(Fortran77最高只支持7维):

integer a(D1,D2,...,Dn)	! n 维数组
a(I1,I2,...,In)	! 使用n维数组

PS:其实可以在声明数组时修改索引,比如:

integer a(0:5)	! a(0)~a(5)6个元素
integer a(-3:3) ! a(-3)~a(3)7个元素

数组内容的设置

Fortran里面给数值赋予初值的方法很多,可以用DATA 赋值:

DATA A /1,2,3,4,5/
INTEGER A(5)
DATA A /5*3/	! 在此指有53

还有一种“隐含式”循环功能
DATA (A(I), I=2,4) /2,3,4/
这里是设置A(2)=2, A(2)=3, A(4)=4
当然对于隐含的循环还可以修改步长(A(I), I=2,10,2)

在Fortran 90里面可以省略掉 DATA 的描述,直接设置初值
integer :: a(5)=(/1,2,3,4,5/)
注意这里的括号和除号之间不能有空格,还可以借助隐含式的功能
integer :: a(5) = (/1,(I, I=2,4),5/)
同样还可以设置二维数组

integer :: m(2,2)
data((m(r,c), r=1,2),c=1,2) /1,2,3,4/

注意对于隐含式而言是先进行内部的循环再进行外部的循环。

Fortran还可以对整个数组赋一个值 integer :: a(5)=5

假设数组 a,b 是两个规模一样的数组,则下列操作都是对于数组中每个元素的操作,最后得到的结果也为同样规模的数组

c = a + b
c = a - b
c = a * b
c = a / b
c = sin(a)
c = a > b !此时为逻辑数组

对于部分数组的操作主要是通过冒号来进行

a(3:5)	! 取a(3) a(4) a(5)
a(3:)	! 取a(3)及之后的所有元素
a(1:5:2)! 取a(1) a(3) a(5)
a(1:10) = a(10:1:-1) ! 对a进行翻转

在Fortran 95里面新增加了功能 where 是取出部分数组进行设置,要注意的是 wheredo 的用法基本一致但是前者的代码更简洁而且支持并行;还有就是where的程序模块里面只能出现跟数组有关的命令且涉及到的数组必须是同样维度的!!!
在实际运用过程中where的用法跟if类似,可以嵌套可以命名:

where(a<2)
  b=1
elsewhere(a>5)
  b=2
elsewhere
  b=3
end where

同样是新增加功能的还有forall可以看成是隐含式循环来使用数组的方法,具体用法为:

forall (triplet1[, triplet2 [, triplet3 ...] ], mask)
  ...... ! triplet1 用于赋值数组坐标范围的值
  ...... ! mask 用来做条件判断
end forall

数组的存储

在Fortran里面数组都是一整块的存储空间,多维数组而言则是遵循列优先法则排列,或者称为最高维优先的原则,对于A(i,j) i所在的就是行(低维),j所在的就是列(高维),在存储的时候会优先存储低维的数据,之后再存储高维的数据,比如对于3x3的数组顺序为:
A ( 1 , 1 ) = > A ( 2 , 1 ) = > A ( 3 , 1 ) = > A ( 1 , 2 ) = > A ( 2 , 2 ) = > . . . . . . A(1,1)=>A(2,1)=>A(3,1)=>A(1,2)=>A(2,2)=>...... A(1,1)=>A(2,1)=>A(3,1)=>A(1,2)=>A(2,2)=>......
而这个在C语言里面是恰巧相反的这点非常重要,因为在读取数据的时候是根据cache line一次读取若干个相邻数据,如果相邻调用的数据在存储上也是相邻的,则能大大提高效率。

可变大小的数组

integer, allocatable :: a(:) ! 声明一个可变大小的数组
在声明之后还不能使用还需要配置内存空间
allocate(a(100), stat=error) ! error 为0表示allocate数组成功
相应的还有释放内存空间
deallocate(a)

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值