课程设计Ⅰ设计说明书万年历的实现学生姓名学号班级成绩指导教师数学与计算机科学学院2014年3月9日课程设计任务书2013—2014 学年第2 学期专业:学号:姓名:课程设计名称:课程设计Ⅰ设计题目:万年历的实现完成期限:自2014 年2月24 日至2014 年 3 月7 日共 2 周设计依据、要求及主要内容(可另加附页):1.任务说明运用C/ C++结构体、函数、数据结构等基础知识,按以下要求编程实现万年历的功能: 1)阐述设计思想,画出流程图;2)输入任一年,判断该年是否为闰年;输入年月日计算该日为当年的那一天;3)输入任一年,显示该年的日历,日历包括阳历、星期;4)说明测试方法,写出完整的运行结果,较好的界面设计。
2.要求1)问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么;2)逻辑设计:写出抽象数据类型的定义,各个主要模块的算法,并画出模块之间的调用关系图;3)详细设计:定义相应的存储结构并写出各函数的伪码算法;4)程序编码:把详细设计的结果进一步求精为程序设计语言程序;5)程序调试与测试:采用自底向上,分模块进行,即先调试低层函数;6)结果分析:程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。
算法的时间、空间复杂性分析;7)编写课程设计报告。
3.参考资料。
以上要求中前三个阶段的任务完成后,先将算法流程图交指导老师面审,审查合格后方可进入后续阶段的工作。
设计工作结束后,经指导老师验收合格后将设计说明书打印装订,并进行答辩。
指导教师(签字):教研室主任(签字):课程设计评阅评语:指导教师签名:年月日摘要设计了一个万年历,该万年历具有日历显示功能,年历、月历、日历查询,闰年判断功能和星期查询功能。
本万年历采用VC++6.0作为软件开发环境,利用C语言和数据结构的相关知识,采用函数之间的调用关系实现了万年历的功能。
该万年历的除了简单的日期查询之外,还可以显示公历的节日。
操作简单,界面清晰,易于为用于所接受。
关键词:万年历;函数;查询;参数检查目录1 课题描述 (1)2 需求分析 (2)3 逻辑设计 (3)4 详细设计 (4)5 程序源代码 (7)6 程序调试与测试 (18)7 总结 (24)参考文献 (25)1 课题描述1.1任务运用C/ C++结构体、函数、数据结构等基础知识,按以下要求编程实现万年历的功能:1)阐述设计思想,画出流程图;2)输入任一年,判断该年是否为闰年;输入年月日计算该日为当年的那一天;3)输入任一年,显示该年的日历,日历包括阳历、节日、星期;4)说明测试方法,写出完整的运行结果,较好的界面设计.1.2要求1)问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么;2)逻辑设计:写出抽象数据类型的定义,各个主要模块的算法,并画出模块之间的调用关系图;3)详细设计:定义相应的存储结构并写出各函数的伪码算法;4)程序编码:把详细设计的结果进一步求精为程序设计语言程序;5)程序调试与测试:采用自底向上,分模块进行,即先调试低层函数;6)结果分析:程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果,算法的时间、空间复杂性分析;7)编写课程设计报告。
2 需求分析设计一个万年历程序。
主要功能是能够输出任意年份或月份的日历,程序的输出的月历格式与日常生活中使用的月历格式相同,最好能够支持通过命令行参数指定要输出的年份或月份。
为了更便捷地使用万年历,要注意以下几点:1)日历显示功能。
能根据系统日期进行初始化,如果没有任何输入,则显示系统日期所在月份的月历。
2)日历查询、闰年判断功能。
输入日期进行查询,显示查询日期所在月份的月历,还将显示所在年份是否为闰年。
3)参数检查功能。
如果输入日期不合法,查询将被拒绝,并显示提示信息。
1)在该万年历的设计过程中,主要功能有年历查询,月历查询和日期查询,其功能模块如图3.1所示:图3.1万年历功能模块2)在该万年历中,采用函数之间的调用来完成结果的显示。
先进入菜单选择,选择之后,进入相应的模块(年历查询模块,月历查询模块,日期查询模块和退出模块)中,并进行相关查询。
如图3.2所示:图3.2万年历调用模块月历显示 月历查询日期查询年历查询 2、月历查询3、日期查询4、退出程序1、年历查询2、月历查询3、日期查询4、退出程序1、年历查询 程序进入记录当时的日期离日期还有几天4.1变量说明1)year 表示年份的变量;2)month 表示月份的变量;3)day 表示日期的变量;4)select 表示菜单选择的变量;5)i 表示月份的变量;6)j 表示一个月中的某一天的变量;7)sum 判断某天是一年中的第几天的变量;8)number判断某天离公元1年1月1日还有几天的变量;9)a[] 表示每月天数的数组变量;10)year1 系统时间年份的变量;11)month1 系统时间月份的变量;12)day1 系统时间日期的变量;以上均为整形变量。
4.2各个算法的流程图4.2.1闰年的判断闰年的判断,能被4整除但不能100整除,或者能被400整除的年份为闰年,否则为平年。
日期的查询,就是直接打印该月份的月历。
1)算法程序int isleap(int year) /*判断是否为闰年*/{if(year%4==0&&year%100!=0||year%400==0)return 1;elsereturn 0;}int maxDay(int year,int month) /*每月的天数*/{int a[]={31,28,31,30,31,30,31,31,30,31,30,31}; /*每个月中的天数*/if(isleap( year))a[1]=29; /*闰年2月份有29天*/return a[month-1];}2)流程图开始输入yearyear%4==0&&year%100!=0||year%400==0Y N该年为闰年该年为平年结束4.2.2对天数的判断对天数进行判断确定是星期几:难点在于判断星期,但根据蔡勒公式,可以很容易地有年月日推断出星期:nday=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400+nday;w=nDay%7。
其中:year:要查询的年份;nday: 从该年的一月一日起到改天的天数;w:得出的星期数,w==0表示星期天。
在打印月历时,只要知道第一天的星期,就可以依次输入后面的日期,通过定长度输出日期,在遇到某天是星期六时,就换行输出,因此可以按照月历的格式输出。
1)算法程序int eachyeartotal(int year,int month,int day) /*判断某天是一年中的第几天*/{int i,sum=0;for(i=1;i<month;i++)sum+=maxDay(year,i);sum+=day;return sum;}int week(int year,int month,int day) /*对天数进行判断确定是星期几*/{int number=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day);number=number%7 ;return number;}2)流程图开始输入i,sum=0i<monthYsum+=maxDay(year,i)Ni++结束5程序源代码以下为万年历的源代码(其中包括主函数和12个子函数):/*****************************包含的头文件******************************/#include "time.h"#include "stdio.h"#include "math.h"#include "windows.h"#include "conio.h"/***********************************函数声明*********************************/ int eachyeartotal(int year,int month,int day); /*判断某天是一年中的第几天*/int counterdays(int year,int month,int day);/*判断今天距特定日期的天数*/int week(int year,int month,int day); /*对天数进行判断确定是星期几*/int maxDay(int year,int month);/*每月的天数*/int isleap(int year);/*判断是否为闰年*/void whatweek(int year,int month,int day);/*判断是星期几*/void display(int year ,int month);/*输出年月*/void display1(int year);/*输出年历*/void display2(int year,int month);/*输出月历*/void display3(int year,int month,int day) ;/*输出日历*/void jieri(int month,int day); /*判断是否公历节日*/void getmenu();/* 显示菜单选择*//**************************************主函数*******************************/ void main(){int year,month,day,select,runyear;while(1){void getmenu();printf(" 请输入相应数字:"); /*菜单选择*/ scanf("%d",&select);system("cls");//清屏命令switch(select){case 1: /*当选择为1时显示年历*/ printf(" 年历显示:输入年(如2011):");scanf("%d",&year);runyear=isleap(year);if(runyear==1)printf("\n\n\n该年为闰年\n\n\n ");elseprintf("\n\n\n该年为平年\n\n\n ");if(year>0&&year<10000) /*显示年份从0-10000 */ {display1(year); /*调用函数*/}elsesystem("cls");break;case 2: /*当选择为2显示月历*/ printf(" 月历显示:输入年月(如2011,6):");scanf("%d,%d",&year,&month);if(year>0&&year<10000&&month>=1&&month<=12){display2(year,month);}elsesystem("cls");break;case 3: /*当选择为3时显示日期*/printf(" 日期显示:输入年月日(比如2011,6,23):");scanf("%d,%d,%d",&year,&month,&day);if(year>0&&year<10000&&month>=1&&month<=12&&day>=1&&day<=maxDay(year,month)) {display3(year,month,day);}elsesystem("cls");break;case 4:exit(0);default: /*当输入其他数字时,输入无效,重新输入*/system("cls");printf(" 输入无效,重新输入!\n");}}}/****************************判断是否为闰年****************************/int isleap(int year){if(year%4==0&&year%100!=0||year%400==0)return 1;elsereturn 0;}/*******************************每月的天数*****************************/{int a[]={31,28,31,30,31,30,31,31,30,31,30,31}; /*每个月中的天数*/if(isleap( year))a[1]=29; /*闰年2月份有29天*/return a[month-1];}/***********************判断某天是一年中的第几天************************/ int eachyeartotal(int year,int month,int day){int i,sum=0;for(i=1;i<month;i++)sum+=maxDay(year,i);sum+=day;return sum;}/********************对天数进行判断确定是星期几***************************/ int week(int year,int month,int day){int number=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day);number=number%7 ;return number;}/****************************输出年月*********************************/ void display(int year ,int month){int max,number,i,j=1;number=week(year,month,1);printf(" %4s %4s %4s %4s %4s %4s %4s\n","Sun","Mon","Tue","Wed", "Thu","Fri","sat");for(i=0;i<number;i++)printf(" "); /*1号前的星期补空格*/ while(j<=max){printf("%6d",j);if (i%7==6)printf("\n"); /* 每7格换一行*/i++;j++;}printf("\n\n");}/******************************输出年历****************************/ void display1(int year){int i;printf("\n");for(i=1;i<=12;i++){printf("%d 年%d 月\n\n ",year,i);display(year,i);}}/****************************输出月历****************************/void display2(int year,int month){printf("\n%d 年%d 月\n ",year,month);display(year,month);}/******************************输出日历**************************************/ void display3(int year,int month,int day){whatweek( year,month,day);jieri(month,day);counterdays(year,month, day);}/****************************判断是星期几************************************/ void whatweek(int year,int month,int day){int number;number=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day); number=number%7 ;switch( number){case 0:printf( "\n %d年%d月%d日是星期日",year,month,day);break;case 1:printf( "\n %d年%d月%d日是星期一",year,month,day);break;case 2:printf( "\n %d年%d月%d日是星期二",year,month,day);break;case 3:printf( "\n %d年%d月%d日是星期三",year,month,day);break;case 4:printf( "\n %d年%d月%d日是星期四",year,month,day);break;case 5:printf( "\n %d年%d月%d日是星期五",year,month,day);break;case 6:printf( "\n %d年%d月%d日是星期六",year,month,day);break;default:system("cls");printf(" 出现错误!\n" );}}/*******************************判断今天距特定日期的天数********************/int counterdays(int year,int month,int day){int year1, days0,days1,month1,days, day1;time_t timep;struct tm *p;time(&timep);p=gmtime(&timep);year1=(1900+p->tm_year) ;month1=(1+p->tm_mon) ;day1=(p->tm_mday); /*获取系统时间year1、month1、day1分别为年、月、日*/ days0=(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400+eachyeartotal(year,month,day);days1=(year1-1)*365+(year1-1)/4-(year1-1)/100+(year1-1)/400+eachyeartotal(year1,month1,day1);days=days0-days1; /*计算出两个日期之间的时间差*/printf("\n\n 今天距%d年%d月%d日还有%d天\n\n",year,month,day,days);return days;}/****************************判断是否公历节日*****************************/void jieri(int month,int day){if(month==1)switch(day){case 1:printf(",这天是元旦");}if(month==2)switch(day){case 14:printf(",这天是情人节");}if(month==3)switch(day){case 8:printf(",这天是妇女节");break;case 12:printf(",这天是植树节");}if(month==4)switch(day){case 1:printf(",这天是愚人节");}if(month==5)switch(day){case 1:printf(",这天是劳动节");break;case 4:printf(",这天是青年节");}if(month==6)switch(day){case 1:printf(",这天是儿童节");}if(month==7)switch(day){case 1:printf(",这天是建党节");}if(month==8)switch(day){case 1:printf(",这天是建军节");}if(month==9)switch(day){case 10:printf(",这天是教师节");}if(month==10)switch(day){case 1:printf(",这天是国庆节");}if(month==12)switch(day){case 25:printf(",这天是圣诞节");}}/**********************************显示菜单选择*****************************/ void getmenu(){printf(" ************主菜单************\n\n");printf(" * 1、年历显示*\n\n");printf(" * 2、月历查询*\n\n");printf(" * 3、日期查询*\n\n");printf(" * 4、退出系统*\n\n");printf(" ******************************\n\n");}6 程序调试与测试6.1调试结果通过前期的上网,看有关书籍进行程序源代码的编写,编写完之后通过后期的改错,调试结果没有错误。