Fortran学习2:控制流(1)

昨天学习了Fortran的基础知识之后,对Fortran有了一定的了解,今天开始学习控制流语句;一个程序要运行的话,除了变量的声明,最主要的还是要对变量进行处理操作,这时,控制流就是必备的了。

一、条件判断:

if(!逻辑判断式)then
!逻辑成立时才执行这一段代码
......
else
!逻辑条件不成立的时候,就会执行这一段代码
......
end if
 

其实就是这样的形式:

比如说,很简单的编一个条件判断:判断一个人是否是毕业生:

program main
implicit none
logical student_one_graduate_student
logical student_two_graduate_student
write(*,*)"student_one"
read(*,*)student_one_graduate_student
write(*,*)"student_one"
read(*,*)student_two_graduate_student
if((student_one_graduate_student).eqv.(.true.))then
    write(*,*)"student_one is graduate_student"
else 
    write(*,*)"student_one is not graduate_student"
end if
if((student_two_graduate_student).eqv.(.true.))then
    write(*,*)"studnet_two is graduate_student"
else 
    write(*,*)"studnet_two is not graduate_student"
end if
stop 
end 

结果如下:

就很离谱,为啥Fortran这么搞笑,我搞了半天才发现,根本不能像c++那样直接用==,而是要使用.eqv.来判断,这就很让人麻。

当然,我们可以在一段代码中,连续进行多重判断,从而可以同时判断一个对象的多个条件:

if(!条件判断1)then
!逻辑成立时才执行这一段代码
......
else if(!条件判断2)then
!逻辑条件1不成立,但逻辑条件2成立的时候,执行这一段代码
......
else if(!条件判断3)then
!逻辑条件1、2均不成立,但逻辑条件3成立的时候,执行这一段代码
......
!多个逻辑条件都不成立的情况就执行else后这一段代码
else
......
end if

 

那么有人问了,能不能像c++那样有嵌套判断嘞?答案是肯定的:

if(!条件判断1)then
    if(!条件判断2)then
        if(!条件判断2)then 
            ......
        else if(!条件判断2)then
            ......
    else if(!条件判断3)then
            ......
else
        end if
    end if
end if

 

注:上一段代码和这一段代码的区别就是,上一段代码是针对多个对象进行,但这一段代码则是循序渐进,只有在对象的一个条件成立的前提条件下,才可以判断下一条件。

fortran90的逻辑运算符如下:

==恒等于
/=不等于
>大于
<小于
>=大于等于
<=

小于等于

.and.交集成立,类似于c++的&&
.or.并集成立,类似于c++的 | |

.not.

非,补集成立,类似于c++的!(Fortran里 !是注释符)
.eqv.两表达式的逻辑结果相同
.neqv.两表达式的逻辑结果不相同

 其实这些运算符都没有什么需要真正练习的,不管c++、java、python还是其他任何语言,这些逻辑运算符都是构成控制流所必须的,只有通过使用这些运算符对变量进行判断,才可以将程序指向所需要的地方。

简单的跟着书上练一段代码吧:

! 判断成绩所对应等级
program main
implicit none
integer score
character grade
write(*,*)"Score:"
read(*,*)score
if(score>100)then
write(*,*)"error score"
else if(score>=90)then
grade="A"
else if ((score<90).and.(score>=80))then
grade="B"
else if((score<80).and.(score>=70))then
grade="c"
else if ((score<70).and.(score>=60))then
grade="d"
else if(score<60)then
grade="e"
end if
write(*,*)grade
stop 
end 



执行结果:

! 判断一个坐标处在哪一个象限
program main
! 为什么要用8位?因为你根本不知道要输入的笛卡尔坐标到底多大
integer(kind=8) x
integer(kind=8) y
integer quadrant
write(*,*)"x="
read(*,*)x
write(*,*)"y="
read(*,*)y
if((x>0).and.(y>0))then
quadrant=1
else if((x<0).and.(y>0))then
quadrant=2
else if((x<0).and.(y<0))then
quadrant=3
else if((x>0).and.(y<0))then
quadrant=4
else if((x==0).or.(y==0))then 
quadrant=0
end if 
if(quadrant>0)then
write(*,*)"the point is in quadrant:",quadrant
else
write(*,*)"the point is on axis"
end if 
stop 
end 

 

 要是需要对浮点数进行判断时,就需要避免使用等于的思想来进行判断,其实这个很简单,稍微有一点计算机组成原理的知识就可以明白了,简单来说,浮点数计算时候会产生误差,这个不可避免,因为这是二进制本身决定的,就比如,两数相除,如果不能整除,得到的结果绝对会有误差,所以,理想的等于并不一定就会成立,那么,就对用其他的方法来对浮点数进行等于判断。

举一个很简单的例子:

program example
real(kind=8)a,b
a=1.44
b=1.32
write(*,"(F9.6)")b/a!这会是个无穷小数
stop 
end 

 浮点数的计算误差是无法避免的,所以,判断式中一定要给误差留余地,举一个书上的例子

program example
implicit none
real a,b
real::e
parameter(e=0.0001)
!常量e的作用是定义误差范围
b=4.0
a=SQRT(b)**2-0.1234*b 
if(abs(a-0.0)<e)then
write(*,*)"a=0"
else 
write(*,*)"a!=0"
end if 
stop 
end program example

字符判断没什么好说的,我接触的几个编程语言的字符判断都是一样的形式,axcii码挨个比大小,没啥好说的,比如:abbc>accd

在来一个很偷懒的方法,select case语句,有没有想到啥,哈哈,switch case!!!

select case(variable)
case(Numeric_range_one)
....
case(Numeric_range_one)
....
case(Numeric_range_one)
....
case(Numeric_range_four)
....
case default
!这一段不一定要出现,看你所规定的范围,如果范围够用,不需要
....
end select
//再看看c++
switch (expression)
{
case /* constant-expression */:
    /* code */
    break;

default:
    break;
}

 那么,好玩的来了,往往一个功能可以用多种方式实现,这下我们试试用select case来编写上面的成绩等级划分:

! 判断成绩所对应等级
program main
implicit none
integer score
character grade
write(*,*)"Score:"
read(*,*)score
select case (score)
    case (90:100)
    grade="A"
    case (80:89)
    grade="B"
    case (70:79)
    grade="C"
    case (60:69)
    grade="D"
    case (0:59)
    grade="E"
    case default
    grade="?"    
end select
write(*,*)grade
stop 
end 



GOTO:这是个又爱又恨的角色,共同有害论的普及已经堪比番茄炒蛋的做法家喻户晓了,但是吧,共同可以规避一些风险,当你发现有问题不对的时候,共同就可以跳开可能出问题的代码,继续执行,但我建议还是不要,咱们大不了设断点一个一个排bug,那还是个比较有意思的事情呢。

来吧,做做书后习题:

1、判断一个上班族一个月得交多少税:

select case 和if 都可以,用select case吧:

! question one
program main
integer wage
real rate
write(*,*)"input your wage"
read(*,*)wage
select case (wage)
    case (0:1000)
    rate=wage*0.03
    write(*,*)"rate:3%",rate
    case (1001:5000)
    rate=wage*0.1  
    write(*,*)"rate:10%",rate    
    case (5001:)
    rate=wage*0.15  
    write(*,*)"rate:15%",rate  
end select
stop 
end 
!待会输个十万,希望日后月工资十万,哈哈

 2、输入日期(周几)来查询当晚电视节目

这回用if:

program main
integer day
character(len=20) tel
write(*,*)"input day"
read(*,*)day
if((day==0).or.(day>7))then
stop "error date"
else if((day==1).or.(day==4))then
tel="news"
else if((day==2).or.(day==5))then
tel="TV series"
else if((day==3).or.(day==6))then
tel="cartoon"
else 
tel="movie"
end if
write(*,*)"Tonight's TV show is  ",tel
stop 0
end 

 展示两个结果,一个是错误日期返回,另一个是正确日期输出:

false:

true:

3、从第一个题出发,在加上年龄的限制来计算个人应交税款:

program main
integer wage,age
real rate
write(*,*)"input your age"
read(*,*)age
write(*,*)"input your wage"
read(*,*)wage
if(age<50)then
select case (wage)
    case (0:1000)
    rate=wage*0.03
    write(*,*)"rate:3%",rate
    case (1001:5000)
    rate=wage*0.1  
    write(*,*)"rate:10%",rate    
    case (5001:)
    rate=wage*0.15  
    write(*,*)"rate:15%",rate  
end select
else 
select case (wage)
    case (0:1000)
    rate=wage*0.05
    write(*,*)"rate:5%",rate
    case (1001:5000)
    rate=wage*0.07  
    write(*,*)"rate:7%",rate    
    case (5001:)
    rate=wage*0.1
    write(*,*)"rate:10%",rate  
end select
end if 
stop 
end 
!试试看我会交多少税

18块钱啊!!!一顿午餐没了,难过

4、闰年判断:

闰年是这样的:

(1)年数是4的倍数

(2)年数是100的倍数时,例外,除非年数也能被400整除

program main 
integer year
logical is_leap_year
write(*,*)"input year"
read(*,*)year
if(mod(year ,4)/=0)then 
    if((mod(year ,100)/=0).and.(mod(year ,400)==0))then 
        is_leap_year=.false.
    end if
else 
    is_leap_year=.true.
end if
write(*,*)" IS this year leap year?",is_leap_year
if(is_leap_year.eqv. .true.)then
write(*,*)"366 days"
else 
write(*,*)"365 days"
end if 
stop 
end

T:

F: 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值