程序设计B10080312.docx
- 文档编号:30399549
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:20
- 大小:32.43KB
程序设计B10080312.docx
《程序设计B10080312.docx》由会员分享,可在线阅读,更多相关《程序设计B10080312.docx(20页珍藏版)》请在冰豆网上搜索。
程序设计B10080312
程序设计报告
(2011/2012学年第一学期)
题目:
万年历系统程序
专业统计信息
学生姓名于大海
班级学号B********
指导教师吴家皋
指导单位计算机学院计算机软件教学中心
日期2011年10月19日
评分细则
评分项
优秀
良好
中等
差
遵守机房规章制度
上机时的表现
学习态度
程序准备情况
程序设计能力
团队合作精神
课题功能实现情况
算法设计合理性
用户界面设计
报告书写认真程度
内容详实程度
文字表达熟练程度
回答问题准确度
简短评语
教师签名:
年月日
评分等级
备注
评分等级有五种:
优秀、良好、中等、及格、不及格
万年历程序
一、课题内容和要求
该系统要求实现一个简单、实用的日历打印程序。
主要功能为在屏幕上显示任意年月的月历,且要按指定的格式输出。
通过此课题,熟练掌握数组、格式输出、文件的各种操作,以及基本的日期算法思想的应用。
通过本项课程设计,可以培养独立思考、综合运用所学有关相应知识的能力,能更好的巩固《C语言程序设计》课程学习的内容,掌握工程软件设计的基本方法,强化上机动手编程能力,闯过理论与实践相结合的难关!
更加了解了c语言的好处和其可用性!
同时增加了同学之间的团队合作精神!
更加也体会到以后在工作中团队合作的重要性和必要性!
通过C语言课程设计,使学生了解高级程序设计语言的结构,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。
为后续各门计算机课程的学习和毕业设计打下坚实基础。
二、需求分析
(1)用户从键盘任意输入一个日期,如:
2008.8.8。
程序就能打印该日期所在月的月历。
(2)月历输出格式如下(重要节假日要在该日期后用*号标注出来):
2008August
-------------------------------------------------------
SunMonTueWedThuFriSat
1*2
3456789
10111213141516
17181920212223
24252627282930
31
(3)需要实现的功能
1)输入日期,显示该日期所在月的月历。
2)可选择显示下一月、上一月的月历。
3)可选择显示下一年、上一年的月历。
4)重要节假日需用一个文本文件进行设置,文件格式自定。
程序应通过读取节假日文件的信息来对月历上的节假日日期进行标注。
(4)界面功能要求:
1)采用友好的字符界面,实现一个功能控制菜单。
每次操作都从该菜单选择,利用循环结构使得一次运行程序可进行多次操作
三、概要设计
【一】由于万年历具有以下特点:
1。
平年365天(52周+1天),闰年366天(52周+2天)。
平年2月28天,闰年2月29天。
由于公元1月1日设为星期六,故3月1日为星期三。
——注意这个“三”
为使算法达到最简,故本算法以“星期”为计算单位。
且选3月1日为基月。
2。
每400年整一闰,或每4年且不为百年的一闰。
(原因:
地球绕太阳一周的时间是365天5小时46秒,为了使一年的天数为整数,将一年的天数定为365天,余下的时间积累起来,四年就是23小时15分4秒,将近一天,把这一天加在某年的二月而成29天,该年称为闰年,其它年称为平年。
但四年加一天又多用了44分56秒,这个数积满400年为三天。
因此400年中只能有97个闰年,所以凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
)
所以百年%4=0闰或(年%4=0并且年<>0)闰。
3。
每4年(3个平年+1个闰年)共208周+5天——注意这个“5天”
每百年共100*(208周+5天)-1天=5217周+5天——注意这个“5天”(整百年暂设为平年)
每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和
“1天”(4个整百年只有一个闰年)
即400年一轮回!
(原来万年历400年前是一家)
【二】根据万年历以上特点进行编写:
首先对万年历年、月、日进行编写,编写程序先定义每月的天数为28天,如月份为1、3、5、7、8、10、12就定义天数为31天反之如果月份为4、6、9、11就输出天数为30天,由上可见2月份为28天但是如果为闰年就有29天就要定义另一个函数#defineYear(x)(x%4==0&&x%100!
=0||x%400==0)?
1:
0当为闰年时可得1加上该程序便可得到每月的天数。
具体程序见(五、万年历程序)
再对其中的星期进行编写:
由于公元1月1日设为星期六,故3月1日为星期三,可以用万年3月1日星期算法(特别是那个三)
由于其公式为:
某年3月1日星期几=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7
某年3月1日星期几=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7
或某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
闰4百年3月1日星期算法(百年%4=0)
其公式为:
某年3月1日星期几=(年+年/4+月星期表+日+2天)%7
例:
0000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
1600年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
2001年3月1日星期几=(1+1/4+0+1+2)%7=4%7=星期四
2004年3月1日星期几=(4+4/4+0+1+2)%7=8%7=星期一
2008年3月1日星期几=(8+8/4+0+1+2)%7=13%7=星期六
2042年3月1日星期几=(42+42/4+0+1+2)%7=55%7=星期六
平4百年3月1日星期算法(百年%4<>0)
其公式为:
某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
例:
1700年3月1日星期几=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:
1700年是平年)
1800年3月1日星期几=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:
1800年是平年)
1900年3月1日星期几=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:
1900年是平年)
1901年3月1日星期几=(19%4*5+1+1/3+0+1+2)%7=19%7=星期五
1918年3月1日星期几=(19%4*5+18+18/4+0+1+2)%7=(15+22+3)%7=40%7=星期五
1958年3月1日星期几=(19%4*5+58/4*5+58%4+3)%7=(15+70+2+3)%7=90%7=星期六
1988年3月1日星期几=(19%4*5+88/4*5+88%4+3)%7=(15+110+0+3)%7=128%7=星期二
1999年3月1日星期几=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一
2100年3月1日星期几=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意:
2100年是平年)
2101年3月1日星期几=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二
2102年3月1日星期几=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三
2103年3月1日星期几=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四
2104年3月1日星期几=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意:
2104年是闰年)
9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一
注:
按400年一轮回!
(400年前是一家)的说法
1600年,2000年是一样的;
1700年,2100年是一样的;
1800年,2200年是一样的;
1900年,2300年是一样的。
其中万年某日星期算法
其公式为:
某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
通同星期偏差表
闰年1月2月3月4月5月6月7月8月9月10月11月12月
天数312931303130313130313031
星期360351362402
平年1月2月3月4月5月6月7月8月9月10月11月12月
天数312831303130313130313031
星期400351362402
为对以上的万年历星期的算法是正确的对其进行了以下的计算:
⒈对于二十世纪任意日期可以用公式某日星期几=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7=(19%4*5天+年+年/4+平年月星期表+日+2天)%7=(15天+年+年/4+平年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
1900年元旦1日=(0/4*5+0%4+1+3)%7=(0+0+4)%7=4
1月表=4(平年)故4+4=1即1900年元旦是星期一
1949年国庆1日=(49/4*5+49%4+1+3)%7=(60+1+4)%7=2
10月表=4(平年)故4+2=6即1949年国庆是星期六
1999年12月31日31日=(99/4*5+99%4+31+3)%7=(120+3+34)%7=3
12月表=2(平年)故2+3=5即1999年12月31日是星期五
⒉对于二十一世纪新前年虫算法(20%4*5=0)可以用公式:
某日星期几=(百年%4*5天+年+年/4+闰年月星期表+日+2天)%7=(20%4*5天+年+年/4+闰年月星期表+日+2天)%7以下就是根据上面对其进行的计算:
2000年元旦1日=(0+0/4+1+2)%7=(0+0+1+2)%7=3
1月表=3(闰年)故3+3->6即2027年元旦是星期六
2018年春节16日=(18+18/4+16+2)%7=(18+4+16+2)%7=5
2月表=0(平年)故0+5=5即2018年春节是星期五
2099年12月31日31日=(99/4*5+99%4+31+2)%7=(120+3+33)%7=2
12月表=2(平年)故2+2=4即2099年12月31日是星期四
【三】结合分析编写相应程序
主程序:
#include
#include
#include
intweek(inty,intm,intd);
intIsmemday(intm,intd,intM[]);
voidprindate(inty,intm);
voidCreate();
voidGetmenu();
voidDwjian();
typedefstructMemday
判断闰年:
if(y%400==0||y%4==0&&y%100!
=0)monthday[1]=29;
elsemonthday[1]=28;
判断星期几:
intweek(inty,intm,intd)
{
intwday;
if((m==1)||(m==2))
{
y--;
m+=12;
}
wday=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
return(wday);
}
判断某天是否是节假日:
intIsmemday(intm,intd,intM[])
{inttemp=0,i,j,k=0;
for(i=0;i if(m==mem[i].month) for(j=0;j if(d==mem[i].day) {temp=1;M[k++]=i;} returntemp; 四、源程序代码 #include #include #include intweek(inty,intm,intd);//定义年,月,日 intIsmemday(intm,intd,intM[]); voidprindate(inty,intm); voidCreate(); voidGetmenu(); voidDwjian(); typedefstructMemday { intmonth,day; }Memday; Memdaymem[100];//定义100个这样的纪念日 intM[30];//将一个月赋值30天 intmonthday[12]={31,28,31,30,31,30,31,31,30,31,30,31}; charmonth[12][10]={"January","February","March","April","May","June","July","August","Septemb","October","November","December"};//定义1到12月的英文 intmaxday=0; FILE*fp; intmain() { inty,m=1,d=1; charorder; Dwjian(); Getmenu(); order='M'; do{ switch(order) { case'M': { printf("【M】菜单【O】查询\n"); printf("【A】/【D】上/下月\n"); printf("【W】/【S】上/下年\n"); printf("【N】新建一个节日\n"); }break; case'O': { printf("请输入一个日期: \n"); scanf("%d.%d",&y,&m); prindate(y,m); printf("\n返回主菜单: 【M】\n"); printf("【A】/【D】上/下月\n"); printf("【W】/【R】上/下年\n"); printf("结束请按【#】键\n\n"); }break; case'D': //D分程序的结构(执行D程序) {if(m+1<=12) prindate(y,++m); else prindate(++y,1); }break; case'A': //执行A程序 {if(m-1>0) prindate(y,--m); else prindate(--y,12); }break; case'S': //执行S程序 {if(y-1>0) prindate(++y,m); else printf("所查询年份超出范围! "); }break; case'W': prindate(--y,m);break; case'N': Create();break; default: break; } printf("\n"); }while((order=getchar())! ='#'); fclose(fp); return0; } intweek(inty,intm,intd)//判断星期几 { intwday; if((m==1)||(m==2)) { y--; m+=12; } wday=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7; return(wday); } voidprindate(inty,intm)//打印某月 {intw,d,i;//intj; if(y%400==0||y%4==0&&y%100! =0)monthday[1]=29; elsemonthday[1]=28;//判断闰年 printf("\n%d年%s\n",y,month[m-1]); printf("----------------------------------\n"); printf("日一二三四五六\n"); printf(""); for(d=1;d<=monthday[m-1];d++) { w=week(y,m,d); if(d==1) { for(i=0;i } if(d<10) if(! Ismemday(m,d,M)) printf("%d",d); else {printf("%d*",d);} else if(! Ismemday(m,d,M)) printf("%d",d); elseprintf("%d*",d); if(w==6)printf("\n"),printf(""); } printf("\n"); return; } voidCreate()//创建一个新纪录 { Memdaymem; charch; do{ printf("请输入一个新纪录: \n"); printf("月: ");scanf("%d",&mem.month);printf("\n"); printf("日: ");scanf("%d",&mem.day);getchar(); fwrite(&mem,sizeof(Memday),1,fp); printf("继续创建: 【1】是/【0】否\n"); ch=getchar(); if(ch=='0') break; }while (1); return; } intIsmemday(intm,intd,intM[])//判断某天是否是节假日 {inttemp=0,i,j,k=0; for(i=0;i if(m==mem[i].month) for(j=0;j if(d==mem[i].day) {temp=1;M[k++]=i;} returntemp; } voidGetmenu()//菜单页面 {inti; printf("********************欢迎您使用本万年历程序********************\n"); for(i=0;i<20;i++)printf("%c",1);printf("");for(i=0;i<20;i++)printf("%c",1);printf("\n"); printf("请您按照提示输入\n\n"); } voidDwjian()//读取文件 { fp=fopen(“B10080312.rec","rb+"); if(! fp) { printf("文件B10080312.rec不能正常打开! "); exit (1); } maxday=0; while(fread(&mem[maxday++],sizeof(Memday),1,fp)); return; } 五、测试数据及其结果分析 1.当对上面的程序进行了调试后运行会出现下面所示: 屏幕上显示万年历菜单,满足了第一条要求“界面功能要求: 采用友好的字符界面,实现一个功能控制菜单”。 2.根据提示在光标处按下“O”后回车,将会显示: ”输入年月”,根据提示输入,会显出对应的月历 2008August ------------------------------------------------------- SunMonTueWedThuFriSat 1*2 3456789 10111213141516 17181920212223 24252627282930 31 以上的显示也证明了条件的第2条”以输入日期,显示该日期所在月的月历” 3. 在光标处按下“A”后回车,将会显示: 2008July ------------------------------------------------------- SunMonTueWedThuFriSat 12345 6789101112 13141516171819 20212223242526 2728293031 在光标处按下“D”后回车,将会显示: 2008Septemb ------------------------------------------------------- SunMonTueWedThuFriSat 123467 891011121314 14151617181920 21222324252627 282930 以上的显示也证明了条件的第3条“显示下一月、上一月的月历” 4.在光标处按下“W”后回车,将会显示: 2007August ------------------------------------------------------- SunMonTueWedThuFriSat 1*234 567891011 13141516171819 20212223242526 2728293031 在光标处按下“S”后回车,将会显示: 2009August ------------------------------------------------------- SunMonTueWedThuFriSat 1* 2345678 9101112131415 161718192
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 B10080312