《c语言综合练习打印日历教程附完整源程序》由会员分享,可在线阅读,更多相关《c语言综合练习打印日历教程附完整源程序(14页珍藏版)》请在金锄头文库上搜索。
1、文档供参考,可复制、编制,期待您的好评与关注! 综合练习 打印日历练习的功能是:由用户输入一个年后,然后就可以分月输出当年的年历。例如输入2010,则输出2010年的年历。如图,图中显示的年历的一部分:学习目标:继续熟悉数组的使用; 继续熟悉函数的使用了解程序算法设计及N-S流程图;综合使用函数和数组完成设计任务一 分析程序算法图2 算法分析图先来分析要解决的问题,如图2程序算法分析如下:1. 整个程序大致可以分为两个主要部分:输入年份;打印该年的日历,如图2所示。2. 打印日历时,为了清楚的知道打印的是哪一年的日历,先打印年份,接着从1月12月,分别打印个月份的名称(英文缩写),然后打印星期
2、的名称(英文缩写),最后在打印当月的日历,如图2所示。3. 要打印某月的日历,首先必须生成当月日历,然后在打印,如图2所示。4. 生成每个月的日历,需要知道当月有多少天,当月每一天是星期几,然后生成当月日历并保存,如图2所示。5. 要知道每月有多少天是比较容易的,除了2月份外,其它月份的天数都是确定的,关键就是确定2月份有几天,如图2所示。6. 如果当年是闰年,则2月份有29天,否则为28天。如图2所示。7. 要想确定当月每一天是星期几,需要知道当年第一天是星期几,然后类推,每7天一个周期,如图2所示。8. 经过以上的47步,可以生成日历,然后设计存储格式,保存日历。9. 设计好输出格式,打印
3、已生成的日历即可,如图2所示。将图2加以综合和细化,最终可以得到整个程序的NS流程图,如图3所示。图3 算法分析NS流程图二、按功能划分函数经过上面的分析,发现在这个程序设计中有几个关键部分: 确定每月有多少天,关键是确定当年是否为闰年。 确定每天是星期几,关键是确定当年1月1日是星期几。 设计数据的存储格式和打印格式。对于较复杂的程序,可以把功能分解,每个小功能用一个函数实现,使程序的总体结构更加清晰。在这个程序中,应考虑使用以下4个函数。函数1: int leapyear(int year),判断year年是否是闰年。函数2: void print2(int month,int t),按月
4、打印日历。函数3: void calendar(int year),按月生成日历。函数4:main()函数。任务二 确定每个月的天数 除了闰年外,每个月有多少天是确定的,所以首相确定非闰年每个月有多少天,然后判断当年是否是闰年,就可以确定当年的2月份有几天。一、 确定非闰年每年有多少天可以使用一维整型数组monthday来存放每个月的天数,代码如下:int monthday13=0,31,28,31,30,31,30,31,31,30,31,30,31;数组长度定义为13,是因为这样定义赋值后“monthday1=31”,表示1月份的天数是31天,比较符合我们的日常习惯,元素monthday0
5、没有使用。二、 确定当年2月有多少天如果是闰年,则2月份29天,闰年的规定:凡是年份能够被4整除、且不能被100整除的是闰年;凡是年份能被400整除的也是闰年;除此以外的年份都不是闰年。程序段如下:if(year%4=0)&(year%100!=0) |(year%400=0) monthday2=29;为了提高程序的可读性,实现程序的模块化设计,对闰年的判断设计成函数leapyear();闰年判断函数int leapyear(int year) if(year%4=0)&(year%100!=0) |(year%400=0) return 1; else return 0; 任务三 确定当年
6、的每天是星期几确定每天是星期几,关键是确定当年的1月1日是星期几。在公元日历的编排中,公元元年几0001年1月1日是星期一,对于输入的年号year,year年的1月1日是星期几可以用下列公式计算:todayweek=year+(year-1)/4 - (year-1)/100 + (year-1)/400%7 注:此算法可以见另一附件“计算每年的第一天星期几”文档。当年第一天是星期几判断出来了,就可以一次推算以后的日子是星期几。任务四 设计数据存储格式,生成各月日历必须为所有需要存储的数据设计存储结构,有了存储结构就可以存储生成的每个月的日历。一、 设计数据的存储格式 使用一维整型数组mont
7、hday存放每个月的天数。 int monthday13=0,31,28,31,30,31,30,31,31,30,31,30,31; 使用二维字符数据monthname存放每个月的英文名称。char monthname136=“”,”JAN”,”FEB”,”MAR”,”APR”,”MAY”,”JUNE”,”JULY”,“AUG”,”SEP”,”OCT”,”NOV”,”DEC” ; 使用二维数字符数组weekday存放一周每一天的星期的英文名称。 char weekday86=“SUN”,”MON”,”TUE”,”WED”,”THU”,”FRI”,”STA”,”SUN”; 使用二维整型数组mo
8、nth_odd、month_even存放奇数月、偶数月的日历int month_odd67; month_even67; 因为每周7天,一个月最多的时候是31天,所有月历最多只需要6行,这样就可以用一个6行7列的二维数组month_odd67、month_even67存放一个月的日历,如表1所示:初始化日历数组 j i0SUN1MON2TUE3WED4THU5FRI6STA000000001000000020000000300000004000000050000000注:首列是星期天。 初始化二维整型数组month_odd,所有元素为0。for(i=0;i5;i+) for(j=0;j6;j+
9、) month_oddij=0; 二、 生成日历(1) 设计变量用变量month表示当前月份,用变量today表示当前日期,用变量todayweek表示当前日期的星期。(2) 日历生成方法分析假设已判断出当年1月1日是星期三,怎样生成1月份的日历呢?已知1月份有31天,需要将131依次存入数组month_odd当中,因为1月1日是星期三,所以首先将“1”存放在第1行(用变量odd_line表示行,“odd_line=0”表示第一行)第四个位置month_odd03中,表示1日是星期三,如表102所示,然后将“2”存放在month_odd04中,将“3”存放在month_odd05中,将“4”存
10、放在month_odd06中,已经到了第一行最后一个位置,下一个日期是星期日,则应存入下一行,也就是说,当变量todayweek等于7时,就应该换行,在下一行存储,而且星期应从星期六重新变成星期日,所以变量todayweek的值应重新赋值为0。这样,每存放7个数就换一行,直至31个数全部存放完毕,如表2所示。表2 存储日期后的日历数组 j i0SUN1MON2TUE3WED4THU5FRI6STA000012341567891011212131415161718319202122232425426272829303150000000(3) 生成某月日历,程序段如下:today1; /从1日开始
11、存放odd_line=0; /从第1行开始存放while(today=monthdaymonth) /从1日开始,直到monthdaymonth,/当月每个日期都要存放 month_oddodd_linetodayweek=today; /将当前日期存放在指定位置todayweek+; /星期加1today+; /日期加1if(todayweek=7) /如果存放完每行最后一个元素,则一下元素位置要换行 todayweek=0; /星期从星期六变回到星期日 odd_line+; /行数加1(4) 生成12个月的日历1月份日历生成完毕后,保存在数组month_odd中;然后继续生成2月份的日历,
12、保存在数组month_even中。2月1日是星期几,可有1月31日的星期得到,变量todayweek的值继续使用,而表示当前日期的变量则要返回到“1”,变量today需要重新赋值today1,表示行数的变量odd_line也要重新赋值“odd_line=0”。与生成1月份日历的方法类似,可将2月份日期逐一存入数组month_even中。同理,继续生成其它月份日历,直到12个月的日历全部生成打印完毕。生成12个月日历的程序段如下:for(month=1;month=12;month+) .任务五:设计打印格式,输出日历使用函数print2(int month, int line)来完成日历的打印
13、,每生成两个月的日历,就打印出来,然后再生成接下来两个月的日历。日历打印函数如下:void print2(int month, int line) int i, j,x;/* 首先输出日历上相应的月份名称 */printf(* %s * ,monthnamemonth); printf( * %s * n,monthnamemonth+1);/* 输出日历上的星期名称 */for(x=0;x=1;x+) for(i=0;i=6;i+) printf(%5s,weekdayi); printf( ); /* 输出日期,总共需要输出0到line行for(i=0;i=line;i+) for(j=0;j=6;j+) /每行需要输出0到6,即星期日到星期六共7个日子 if(month_oddij=0