C语言课程设计报告
-----万年历
设计人:贾伟涛
学号:2013010912
班级:13电信应电班
指导老师:张伟
日期:20##年6月9日
内容提要
通过大一下学期对C语言的学习,了解到了很多C语言的相关知识。学习的过程虽然有很多困惑,但是当自己能够独立的看懂和独立的完成一个简单的程序时,心中就会收获无限的喜悦和成就感。我虽然可以看懂一些简单的程序,编写一些简单的计算程序,更多的是学会了一种思想——编程,它让我在去思考很多日常生活中的事物是怎么样通过一个个小小的函数实现功能的,激发我对c语言的兴趣。
C语言是近年在国内外得到迅速推广应用的一种机器语言。C语言功能丰富,表达能力强,使用灵活方便,应用面广,目标程序效率高,可移植性好,既具有高级语言的优点,又具有低级语言的许多特点。因此,C语言特别适合于编写各种软件。
在这次的课程设计中我将把日常生活中最经常接触的——日历的查询,利用C语言的程序编成一个简单的万年历查询系统。通过这个小小的系统可以实现很多功能。在程序中你能看到很多熟悉的C语言关键字,同时也加入了很多自己课外了解到的一些关键字。在不断的调试中最终才获得最为完整的程序。接下来就是我的C语言课程设计的具体内容来了,大家拭目以待吧!
目录
一、 系统功能和数据说明-----------------------
二、 问题分析---------------------------------
三、 程序总体设计及功能结构框图---------------
四、 程序流程图-------------------------------
五、 源程序代码-------------------------------
六、使用说明---------------------------------
七、个人心得---------------------------------
八、参考文献---------------------------------
一、系统功能和数据说明
(一)功能简介
在日常生活中能接触到很多不同类型的日历,在日历上我们通常希望它能简单明了的给我们最想要的日期信息。在我的万年历系统当中,就是将日历,月历做的简单明了,很方便我们的查询使用。下面是它要实现的一些基本功能:
C语言编写万年历查询系统:
(1)输入年份,判断是否为闰年
(2)输入年月日,判断是星期几
(3)输入年份,打印出12个月的月历
(4)输入年月,打印出本月的日历
另新增:
(1)对输入指令错误的提示
(2)加入了调用系统时间函数
(3)还添加了欢迎界面并进行界面优化
(二)程序中的数据说明
①int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
这是定义的关于每个月天数的数组,根据大小月以及二月份的特殊情况将每个月的天数变为数组中的元素存入数组当中。其中days[1]=28,是将闰年二月的天数28天作为初始元素存入。在经过yearMonth函数后就可以给days[1]中存入正确的月天数。
② tm *tp;
char *week[]={"一","二","三","四","五","六","日"};
这两组数据设计都利用了指针定义,利用指针可以提高程序的可读性,可以更方便使用。这两个数组的作用是用于调用系统时间,而定义的星期数组*week[]和年月日变量*tp,由于还没学到指针,在这里查阅了很多资料,并也借鉴了前辈们的很多程序。
二、问题分析
对于闰年的判断,能被4整除但不能被100整除,或者能被400整除的年份为闰年,否则为平年。日期的查询,就是直接打印改天所在月份的月历。
程序难点在于判断星期,但根据公式,我们可以很容易地用年月日推断出星期:
weekday=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7;
其中year:要查询的年份
day:从该年的一月一日起到该天的天数
weekday:得出的星期数。
在打印月历时,只要知道第一天的星期,就可以依次输入后面的日期,通过一定长度输出日期,在遇到某天时星期天时,就换行输出,因此可以按照月历的格式输出。
对于初始输入当前系统时间,可以通过<time.h>中的time 和localtime函数取出系统时间进行初始化。
判断日期是否合法,
if((year>=3000||year<=1600)||(month>=12||month<0)||(day>=31||day<=0))
{
system("CLS");
printf(" 输入错误,系统及即将返回!");
Sleep(3000);
goto tz;
}
可以先判断年月日是否有小于0的值,月和日是否有超出最大值12和31 ,如果通过此判断合法,再判断是否时闰年,如果时闰年,则判断二月份是否满足要求,闰年二月份不能超过29天,平年二月份不能超过28天。在查询过程中,如果发现输入不合法或者不满足输入要求,则提示错误,并返回主菜单。
三、程序总体设计及功能结构框图
(一)功能结构框图
(二)程序设计
头文件:#include<stdio.h>//标准输入输出函数
#include<stdlib.h>//清屏函数system()
#include<windows.h>//延时函数Sleep()
#include<time.h> //调用系统时间函数time()
在程序中运用了大量的自定义函数,都涉及为了使程序更简介明了。其中有:
int isLeapYear(int year)//判断是否为闰年
void hy()//欢迎信息;
void Time() //获取系统时间;
int whichWeekday(int year, int month, int day)//判断某天为星期几; void yearMonth(int year, int month)//打印某年某月的月历;
void monthDay(int year)//输入年份,打出个月历;
void menu()//主菜单;
void main()//主函数;
这些函数的定义及其相应的内部程序共同构筑起了这个万年历查询系统的总程序。其中isLeapYear函数是用来判断输入的年份是否为闰年,实现了预计功能的第一个方面;whichWeekday函数则是为了实现判断星期而编写的;yearMonth函数则是为了实现月历而编写的;Time()函数则是为调用系统时间而编写,该Time()函数采用指针形式定义了*week[]数组和*tp变量;yearMonth,monthDay 这两个函数的共同使用就能够完成输出年历的功能。
四、程序流程图
(一)总流程图
(二)算法说明
1. 总天数的算法:
isLeapYear函数的使用,判断出了输入年份是否为闰年的信息。判断一年是否为闰年的方法是:该年分而能被4整除但不能被100整除,或者是能被400整除。
判断是否为闰年的流程图:
2.输入日期计算星期几:
利用whichWeekday函数可以判断出星期,然后对于输入的日期可以通过公式weekday=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7计算就可以输出相应的星期数。
int whichWeekday(int year, int month, int day)//判断某天为星期几
{
int weekday;
if (month == 1 || month == 2)//公式中要把月和月换成是上一年的月和月
{
month += 12;
year -= 1;
}
weekday=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7; //计算星期的公式
return weekday+1;
}
3. 对输入信息的汇总:
void yearMonth(int year, int month)//打印某年某月的月历,void monthDay(int year)//输入年份,打出个月历;通过这两个函数可以将输入数据的具体信息通过完整日历的形式表示出来。
void yearMonth(int year, int month)//打印某年某月的月历
{
int i,j=0;
int weekday; //计算这个月第一天是星期几
weekday = whichWeekday(year, month, 1);
printf("\n %d年%d月\n",year,month);
printf(" ------------------------------------------------\n");
printf(" 星期一星期二星期三星期四星期五星期六星期天\n");
if(isLeapYear(year) && month == 2)
days[1] = days[1] + 1;
printf(" ");
for(i = 1; i < weekday; i ++)
printf(" ");
for(i = 0; i < 8 - weekday; i ++)
{
printf("%6d", i+1);
printf(" ");
}
printf("\n ");
for(i = 9-weekday; i <= days[month-1]; i ++,j++)
{
if(j == 7)
{
j = 0;
printf("\n ");
}
printf("%6d ", i);
}
printf("\n ------------------------------------------------\n");
}
void monthDay(int year)//输入年份,打出个月历
{
int i;
for(i = 0; i < 12; i ++)
yearMonth(year,i+1);
printf("\n\n");
}
五、源程序代码
#include<stdio.h>//标准输入输出函数
#include<stdlib.h>//清屏函数system()
#include<windows.h>//延时函数Sleep()
#include<time.h> //调用系统时间函数time()
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};//每月的天数,闰年二月要加
int isLeapYear(int year)//判断是否为闰年
{
if(year%4 == 0 && year%100 != 0 || year%400 == 0)
return 1;
else
return 0;
}
void hy()//欢迎信息
{
printf("\n 欢迎使用万年历查询系统\n\n");
Sleep(700);//延时毫秒
printf(" 祝您每天好心情!\n\n\n");
Sleep(1000);
printf(" 版本:v2.0\n\n\n");
Sleep(1000);
printf(" 正在进入功能菜单,请稍候》》\n");
Sleep(5000);//延时秒
}
void Time() //获取系统时间
{
time_t t;
struct tm *tp;
static char *week[]={"一","二","三","四","五","六","日"};
t=time(NULL);
tp=localtime(&t);
printf("\t ─────────────────────\n");
printf("\t\t 系统时间日期:%d年%d月%d日",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday);
printf(" %d:%d:%d ",tp->tm_hour,tp->tm_min,tp->tm_sec);
printf("星期%s\n",week[(tp->tm_wday)-1]);
printf("\t ─────────────────────\n");
}
int whichWeekday(int year, int month, int day)//判断某天为星期几
{
int weekday;
if (month == 1 || month == 2)//公式中要把月和月换成是上一年的月和月
{
month += 12;
year -= 1;
}
weekday=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7; //计算星期的公式
return weekday+1;
}
void yearMonth(int year, int month)//打印某年某月的月历
{
int i,j=0;
int weekday; //计算这个月第一天是星期几
weekday = whichWeekday(year, month, 1);
printf("\n %d年%d月\n",year,month);
printf(" ------------------------------------------------\n");
printf(" 星期一星期二星期三星期四星期五星期六星期天\n");
if(isLeapYear(year) && month == 2)
days[1] = days[1] + 1;
printf(" ");
for(i = 1; i < weekday; i ++)
printf(" ");
for(i = 0; i < 8 - weekday; i ++)
{
printf("%6d", i+1);
printf(" ");
}
printf("\n ");
for(i = 9-weekday; i <= days[month-1]; i ++,j++)
{
if(j == 7)
{
j = 0;
printf("\n ");
}
printf("%6d ", i);
}
printf("\n ------------------------------------------------\n");
}
void monthDay(int year)//输入年份,打出个月历
{
int i;
for(i = 0; i < 12; i ++)
yearMonth(year,i+1);
printf("\n\n");
}
void menu()//主菜单
{
printf(" -----------------------------------------------\n");
printf(" ");
printf(" 万年历查询系统\n\n");
printf(" **************************************************\n");
printf(" ** 1、输入年份,判断是否为闰年 **\n");
printf(" ** 2、输入年月日,判断该日为星期几 **\n");
printf(" ** 3、输入年份,打出个月历 **\n");
printf(" ** 4、输入月份,打出该月的日历 **\n");
printf(" ** 5、退出 **\n");
printf(" **************************************************\n\n");
}
void main()//主函数
{
int num,year,month,day,weekday;
char ch;
while(1)
{
system("CLS"); //清屏
hy();//欢迎信息
tz:system("CLS");//goto语句跳转菜单标志
Time();//调用系统函数
menu();//菜单
printf(" 请输入对应操作:");
scanf("%d", &num);
switch(num)
{
case 1:
{
system("CLS");
t1:printf("\n 请输入年份,确定按‘回车’(格式:):\n");//goto语句标志
scanf("%d", &year);
if(year>=3000||year<=1600)
{
system("CLS");
printf(" 输入错误,系统及即将返回!");
Sleep(3000);
goto tz;
}
if(isLeapYear(year))
printf(" %d年是闰年。\n",year);
else
printf(" %d年不是闰年。\n",year);
printf("提示:\n如继续运行请按\n如回首菜单请按\n如退出请按\n请选择:");
ch=getch();
if(ch=='1')
goto t1;//goto语句返回的t1
if(ch=='2')
goto tz;//执行主函数
if(ch=='0')
exit(0);//退出
break;
}
case 2:
{
system("CLS");
t2:printf("\n 请输入年月日,以空格隔开,确定按‘回车’(格式:6 10):\n");
scanf("%d%d%d", &year,&month,&day);
if((year>=3000||year<=1600)||(month>=12||month<0)||(day>=31||day<=0))
{
system("CLS");
printf(" 输入错误,系统及即将返回!");
Sleep(3000);
goto tz;
}
weekday = whichWeekday(year, month, day);
printf(" 这天是星期%d。\n\n",weekday);
printf("提示:\n如继续运行请按\n如回首菜单请按\n如退出请按\n请选择:");
ch=getch();
if(ch=='1')
goto t2;
if(ch=='2')
goto tz;
if(ch=='0')
exit(0);
break;
}
case 3:
{
system("CLS");
t3:printf("\n 请输入年份,确定按‘回车’(格式:):\n");
scanf("%d", &year);
if(year>=3000||year<=1600)
{
system("CLS");
printf(" 输入错误,系统及即将返回!");
Sleep(3000);
goto tz;
}
monthDay(year);
printf("提示:\n如继续运行请按\n如回首菜单请按\n如退出请按\n请选择:");
ch=getch();
if(ch=='1')
goto t3;
if(ch=='2')
goto tz;
if(ch=='0')
exit(0);
break;
}
case 4:
{
system("CLS");
t4:printf("\n 请输入年份(格式:):\n");
scanf("%d", &year);
printf(" 请输入月份,确定按‘回车’(格式:):\n");
scanf("%d", &month);
if((year>=3000||year<=1600)||(month>=12||month<0))
{
system("CLS");
printf(" 输入错误,系统及即将返回!");
Sleep(3000);
goto tz;
}
yearMonth(year,month);
if(isLeapYear(year) && month == 2)//如果年份为闰年,则月加天
days[1] = days[1] + 1;
printf("提示:\n如继续运行请按\n如回首菜单请按\n如退出请按\n请选择:");
ch=getch();
if(ch=='1')
goto t4;
if(ch=='2')
goto tz;
if(ch=='0')
exit(0);
break;
}
case 5:
{
printf("\n 是否确定退出?\n");
printf(" 确定请按,取消请按");
ch=getch();
if(ch == '2')
goto tz;
else
{
printf(" ");
exit(0);//退出
}
break;
}
default:
{
system("CLS");
printf(" 您的输入的指令有误,请重新输入!!\n\n");
printf("提示:\n如回首菜单请按\n如退出请按\n请选择:");
ch=getch();
if(ch=='1')
goto tz;
if(ch=='0')
exit(0);
break;
}
}
}
}
六、使用说明
运行程序,首先进入欢迎界面,等待3秒后,进入主菜单界面,可看到以下界面
─────────────────────
系统时间日期:20##年6月10日 16:55:14 星期二
─────────────────────
-----------------------------------------------
万年历查询系统
**************************************************
** 1、输入年份,判断是否为闰年 **
** 2、输入年月日,判断该日为星期几 **
** 3、输入年份,打出12个月历 **
** 4、输入月份,打出该月的日历 **
** 5、退出 **
**************************************************
请输入对应操作:
1、在“请输入对应操作:”后面输入功能序号,如需“输入年份,判断是否为闰年”,请输入“1”,其他功能雷同。
2、进入附属界面后会出现以下界面:
请输入年份,确定按‘回车’(格式:2014):
3、可在“请输入年份,确定按‘回车’(格式:2014):”语句后输入年份”2014”,会出现下面界面:
请输入年份,确定按‘回车’(格式:2014):
20##
20##年不是闰年。
提示:
如继续运行请按1
如回首菜单请按2
如退出请按0
请选择:
4、可在“请选择:”后面填写序号,即可得到相应的提示功能。
5、 其他功能做法于上相同,就不一一赘述。
七、个人心得
(略)
八、参考文献
[1]谭浩强。C程序设计(第四版).北京:清华大学出版社,2010
[2]杜 恒。C程序程序设计(理实一体化教程).北京:机械工业出版社,2013
[3]部分资料来源网络,作者不详。在这里对他们表示由衷的感谢