fortran实验报告.docx
《fortran实验报告.docx》由会员分享,可在线阅读,更多相关《fortran实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
fortran实验报告
一:
问题描述和分析
1:
问题描述
编写一个程序,满足一下条件
a,输入一个年、月、日并计算它是本年度的第几天。
b.输入任意一年份,给出该年出生人的属相,如1945年出生的人的属相为“鸡”。
c.显示输出2000~2099年的任何一年的某一月的月历,所要显示的年月有键盘输入。
如2002年5月的月历形式如下;
5月2002年
日一二三四五六
1234567
891011121314
15161718192021
22232425262728
293031
d.显示输出2000~2099年的任何一年的年历,并写入一文本文件中。
e.以上功能都应从菜单中选择执行。
2:
问题分析:
1:
这个程序可以同时在屏幕和文本中输出计算结果。
为了计算不同的问题,引入变量q,当q=1时,计算某年月日是此年的第几天;当q=2时,计算某年的属相;当q=3时,计算月历;当q=4时,计算年历;当q=0时,退出此程序。
2:
难点在于判断星期,但根据蔡勒公式,可以很容易地有年月日推断出星期:
nDay=year-1+(year-1)/4-(year-1)/100+(year-1)/400+nday;
w=nDay%7;
其中year:
要查询的年份;nday:
从该年的一月一日起到该天的天数;w:
得出的星期数,w==0表示星期天。
在打印月历时,只要知道第一天的星期,就可以依次输入后面的日期,通过定长度输出日期,在遇到某天时星期六时,就换行输出,因此可以按照月历的格式输出。
3:
闰年的判断,能被4整除但不能被100整除,或者能被400整除的年份为闰年,否则为平年。
日期的查询,就是直接打印改天所在月份的月历。
4:
判断日期是否合法,可以先判断年月日是否有小于0的值,月和日是否有超出最大值12和31,如果通过此判断合法,再判断是否时闰年,如果时闰年,则判断二月份是否满足要求,闰年二月份不能超过29天,平年二月份不能超过28天。
在查询过程中,如果发现输入不合法或者不满足输入要求,则要求重新输入。
二:
算法、流程图
1:
算法
1定义变量和函数
2输出q值所代表的含义
3输入q
4若q=0,则结束程序
5若q≠0,则若q=1
a:
输入年、月、日
b:
若输入不合法,则输出错误,并返回a;若输入合法,则打开文件并调用子程序
6若q≠1,则若q=2,则
a:
输入年份
b:
打开子程序
7若q≠2,则若q=3,则
a:
输入年、月
8若q≠3,则若q=4,则
a:
输入年份
b:
若输入不合法,则输出错误,并返回a;若输入合法,则打开文件并调用子程序
c:
计算
d:
关闭文件
e:
输出结果
9若q≠4,则输出错误并返回③
10结束程序
2:
流程图
三:
程序源文件
programfirstquestion
implicitnone
integer:
:
q,i,lday
integer:
:
year,month,day,days,mday,ds
character(len=2),dimension(1:
37):
:
tem
print*,'whenq=1,thisprogramcanresolvethequestionthatwhichdaysomedayisinsomeyear!
thisisthequestionone.'
print*,'whenq=2,thisprogramcanobtaintheshengxiaoofsomeyear!
thisisthequestiontwo.'
print*,'whenq=3,thisprogramcanobtainthecalendarofsomemonthofsomeyear(2000-2099)!
thisisthequestionthree.'
print*,'whenq=4,thisprogramcanobtaintheAlmanacofsomeyear(2000-2099)!
thisisthequestionfour.'
print*,'Ifyouwanttoexitfromthisprogram,pleaseinputq=0.'
do
print*,'inputthenumberofq:
'
read*,q
if(q==0)exit
if(q==1)then
2000print*,'inputtheyear,themonthandtheday:
'
read*,year,month,day
if(month>12.or.month<0)print*,'youinputwrongmonth.'
if(month>12.or.month<0)goto2000
callleapday(year,month,day,lday)
if(lday==0)print*,'youinputwrongday.'
if(lday==0)goto2000
callnumday(year,month,day,days)
print'(a14,i3,a18)','Thedayisthe',days,'dayofthisyear.'
open(25,file='days.dat',status='unknown')
write(25,'(a14,i3,a18)')'Thedayisthe',days,'dayofthisyear.'
close(25)
elseif(q==2)then
print*,'inputtheyear:
'
read*,year
callshengxiao(year)
elseif(q==3)then
2001print*,'inputtheyear(2000-2099)andthemonth:
'
read*,year,month
if(year>2099.or.year<2000)print*,'youinputwrongyear,pleaseinputtheyearbetween2000and2099.'
if(year>2099.or.year<2000)goto2001
if(month>12.or.month<0)print*,'youinputwrongmonth.'
if(month>12.or.month<0)goto2001
open(27,file='yueli.dat',status='unknown')
callnyli(year,month,mday,ds,tem)
write(27,"(26x,i2,'月',3x,i4,'年')")month,year
write(27,'(18x,7a4)')'日','一','二','三','四','五','六'
write(27,'(18x,7a4)')(tem(i),i=1,mday+ds)
write(27,*)
close(27)
elseif(q==4)then
2002print*,'inputtheyear(2000-2099):
'
read*,year
if(year>2099.or.year<2000)print*,'youinputwrongyear,pleadeinputtheyearbetween2000and2099.'
if(year>2099.or.year<2000)goto2002
open(28,file='nianli.dat',status='unknown')
domonth=1,12
callnyli(year,month,mday,ds,tem)
write(28,"(26x,i2,'月',3x,i4,'年')")month,year
write(28,'(18x,7a4)')'日','一','二','三','四','五','六'
write(28,'(18x,7a4)')(tem(i),i=1,mday+ds)
write(28,*)
enddo
close(28)
else
print*,'youinputthewrongnumberofq.'
endif
enddo
endprogramfirstquestion
subroutineshengxiao(year)
implicitnone
integer:
:
year,m,n
m=year-1945
if(m>=12.or.m<=-12)then
n=mod(m,12)
else
n=m
endif
open(26,file='shengxiao.dat',status='unknown')
if(n==0)then
print*,'Theshengxiaoofthisyearis:
鸡'
write(26,*)'Theshengxiaoofthisyearis:
鸡'
elseif(n==1.or.n==-11)then
print*,'Theshengxiaoofthisyearis:
狗'
write(26,*)'Theshengxiaoofthisyearis:
狗'
elseif(n==2.or.n==-10)then
print*,'Theshengxiaoofthisyearis:
猪'
write(26,*)'Theshengxiaoofthisyearis:
猪'
elseif(n==3.or.n==-9)then
print*,'Theshengxiaoofthisyearis:
鼠'
write(26,*)'Theshengxiaoofthisyearis:
鼠'
elseif(n==4.or.n==-8)then
print*,'Theshengxiaoofthisyearis:
牛'
write(26,*)'Theshengxiaoofthisyearis:
牛'
elseif(n==5.or.n==-7)then
print*,'Theshengxiaoofthisyearis:
虎'
write(26,*)'Theshengxiaoofthisyearis:
虎'
elseif(n==6.or.n==-6)then
print*,'Theshengxiaoofthisyearis:
兔'
write(26,*)'Theshengxiaoofthisyearis:
兔'
elseif(n==7.or.n==-5)then
print*,'Theshengxiaoofthisyearis:
龙'
write(26,*)'Theshengxiaoofthisyearis:
龙'
elseif(n==8.or.n==-4)then
print*,'Theshengxiaoofthisyearis:
蛇'
write(26,*)'Theshengxiaoofthisyearis:
蛇'
elseif(n==9.or.n==-3)then
print*,'Theshengxiaoofthisyearis:
马'
write(26,*)'Theshengxiaoofthisyearis:
马'
elseif(n==10.or.n==-2)then
print*,'Theshengxiaoofthisyearis:
羊'
write(26,*)'Theshengxiaoofthisyearis:
羊'
elseif(n==11.or.n==-1)then
print*,'Theshengxiaoofthisyearis:
猴'
write(26,*)'Theshengxiaoofthisyearis:
猴'
endif
close(26)
endsubroutineshengxiao
subroutinenyli(year,month,mday,ds,tem)
implicitnone
integer:
:
year,month,days,mday
integer:
:
i,m,ds,dts,q
real:
:
s
character(len=2),dimension(1:
37):
:
tem
callnumday(year,month,1,days)
callmonday(year,month,mday)
s=(year-1)*1.2425+days
ds=int(s-int(s/7)*7)
doi=1,37
tem(i)=''
enddo
tem(ds+1)='1';tem(ds+11)='11';tem(ds+12)='12';
tem(ds+2)='2';tem(ds+13)='13';tem(ds+14)='14';
tem(ds+3)='3';tem(ds+15)='15';tem(ds+16)='16';
tem(ds+4)='4';tem(ds+17)='17';tem(ds+18)='18';
tem(ds+5)='5';tem(ds+19)='19';tem(ds+20)='20';
tem(ds+6)='6';tem(ds+21)='21';tem(ds+22)='22';
tem(ds+7)='7';tem(ds+23)='23';tem(ds+24)='24';
tem(ds+8)='8';tem(ds+25)='25';tem(ds+26)='26';
tem(ds+9)='9';tem(ds+27)='27';tem(ds+28)='28';
tem(ds+10)='10';tem(ds+29)='29';tem(ds+30)='30';tem(ds+31)='31';
print"(26x,i2,'月',3x,i4,'年')",month,year
print'(18x,7a4)','日','一','二','三','四','五','六'
print'(18x,7a4)',(tem(i),i=1,mday+ds)
print*
endsubroutinenyli
subroutinenumday(year,month,day,days)
implicitnone
integer:
:
year,month,day,days,n
logical:
:
leap
callleapyear(year,leap)
n=int(month/2)
if(month<=8)then
if(mod(month,2)/=0)then
days=30*n+31*n+day
else
days=30*(n-1)+31*n+day
endif
else
if(mod(month,2)/=0)then
days=30*(n-1)+31*(n+1)+day
else
days=30*(n-1)+31*n+day
endif
endif
if(month>2)then
if(leap)then
days=days-1
else
days=days-2
endif
endif
endsubroutinenumday
subroutinemonday(year,month,mday)
implicitnone
integer:
:
year,month,mday
logical:
:
leap
callleapyear(year,leap)
selectcase(month)
case(4,6,9,11)
mday=30
case(1,3,5,7,8,10,12)
mday=31
case
(2)
for_feb:
selectcase(leap)
case(.true.)
mday=29
case(.false.)
mday=28
endselectfor_feb
casedefault
endselect
endsubroutinemonday
subroutineleapyear(year,leap)
implicitnone
integer:
:
year
logical:
:
leap
if(mod(year,4)/=0)then
leap=.false.
elseif(mod(year,100)/=0)then
leap=.true.
elseif(mod(year,400)/=0)then
leap=.true.
else
leap=.false.
endif
endsubroutineleapyear
subroutineleapday(year,month,day,lday)
implicitnone
integer:
:
year,month,day,lday
logical:
:
leap
callleapyear(year,leap)
selectcase(month)
case(4,6,9,11)
if(day>30.or.day<1)then
lday=0
else
lday=1
endif
case(1,3,5,7,8,10,12)
if(day>31.or.day<1)then
lday=0
else
lday=1
endif
case
(2)
for_feb:
selectcase(leap)
case(.true.)
if(day>29.or.day<1)then
lday=0
else
lday=1
endif
case(.false.)
if(day>28.or.day<1)then
lday=0
else
lday=1
endif
endselectfor_feb
casedefault
endselect
endsubroutineleapday
四:
结果及其分析
1:
运行结果
问题一:
查询是第几天
问题二:
查询生肖
问题三:
输出月历
问题四:
输出年历
退出程序
输入错误年份和月份时结果
输入错误的q值时情况
2:
结果分析:
1:
经验证该程序中更像数据结果输出正确,基本符合题目要求。
2:
程序使用了选择、循环、函数调用、格式输出输入等基本编程方法。
使用了“goto”等语句,使程序更符合习惯。
3:
该程序考虑到了输入者输入错误的情况。
五:
小结:
通过本学期fortran程序设计的学习,我初步了解和基本掌握了fortran的基础知识。
能够运用fortran语言编写简单的程序。
很大程度提高了程序综合设计能力、分析能力和编程能力,以及自我动手能力。
不足之处,请老师谅解批评指正!