我的心还是热的!
今天有人问了我一个万年历的题,那道题本身不难,因为你只需要写一个函数就可以,但我突发奇想——为什么不把它的全部函数写出来呢?说干就干
(ps如果觉得题目的样例不够的话,可以用手机看日历来对照)。
设计一个万年历,当用户输入年份和月份时,显示这个月的日历表。程序重点是这个月的第一天是星期几和这个月有几天,有了这两个值,只需通过排列,就可以显示这个日历。程序要求用户输入的年份是从1900年开始,已知1900年1月1日是星期一。
日历中每个具体的日期占5个字符宽度,右对齐,上下的分隔线分别是由35个’*’ 连字符构成,表示星期的字符是三个字符,加两个空格分隔。
void ShowDate(int y, int m);
其中,参数y是给定年,参数m是给定月,函数功能是根据给定的年月,显示该月日历。
在这里给出一组输入。例如:
1949 10
***********************************
Sun Mon Tue Wen Thur Fri Sta
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
***********************************
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB
void ShowDate(int y, int m)
{
printf("***********************************\n");
printf(" Sun Mon Tue Wen Thur Fri Sta\n");
int count=GetFirstDayInTable(y,m),i;
for(i=0;i
ok,那么正文开始
int IsLeapYear(int y); /*判断是否闰年,细节不表*/
这个记住定义就好——能被4整除且不被100整除或被400整除
如下:
int IsLeapYear(int y) /*判断是否闰年,细节不表*/
{
if (!(y % 4) && y % 100 || !(y % 400))
return 1;
return 0;
}
这里有俩小细节
1.我只用了if,没有else,这是因为return代表了程序结束,这段代码里有没有else结果不变
所以,不能拘泥于某个形式,要灵活多变
2.我用了个“!”,这个是逻辑非,!(表达式),若表达式为真,则整体为假,反之为真。
int GetDaysofMonth(int y, int m); /*确定某个月的天数,细节不表*/
这里可以借用数组存储数据
int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//全局变量
int GetDaysofMonth(int y, int m)/*确定某个月的天数,细节不表*/
{
if (IsLeapYear(y) && m == 2)
return 29;
return month[m];
}
重点
1.我的数组是个全局变量,这是因为我发现后面的函数还会用到它,所以干脆建个全局
2.if语句的合理应用将代码缩小到了7行,将闰年的月作为特例拿出来,同时可以发现这个if也没有else哦
int GetTotalDays(int y, int m); /*计算从1900年1月开始到给定年月间的天数,不包含给定月的天数,细节不表*/
代码如下
int GetTotalDays(int y, int m) /*计算从1900年1月开始到给定年月间的天数,不包含给定月的天数,细节不表*/
{
int sum = 0,i;
for ( i = 1900; i < y; i++)
{
sum = sum + 365 + IsLeapYear(i);
}
for (i = 1; i < m; i++)
sum += month[i];
if (IsLeapYear(y) && m > 2)
sum++;
return sum;
}
重点
1.俩个循环的使用,一个调控年份,一个调控月份
2.注意在年份的循环中我还引入了一个函数,来判断是否为闰年,而且进行相加,这也是为什么前面的返回值要设置为1或0,因为闰年就是多一天!!!
3.对于闰年2月还是和之前一样当作特殊情况拿出来
int GetFirstDayInTable(int y, int m); /*计算给定年月的第一天在日历表中的位置,返回值为0对应Sun位置,返回值为6对应Sta位置,细节不表*/
代码如下
int GetFirstDayInTable(int y, int m)/*计算给定年月的第一天在日历表中的位置,返回值为0对应Sun位置,返回值为6对应Sta位置,细节不表*/
{
int sum= GetTotalDays(y, m);
sum %=7;
if (sum == 6)
return 0;
return sum+1;
}
这个就比较好理解了,余数为6说明是周日返回零,其他就是“sum+1 ”,(因为最开始是周一)。
void ShowDate(int y, int m); /*显示日历*/
这个就是题目要求写的,,代码如下
void ShowDate(int y, int m)
{
printf("***********************************\n");
printf(" Sun Mon Tue Wen Thur Fri Sta\n");
int count = GetFirstDayInTable(y, m);
int i;
for (i = 0; i < count; i++)
printf(" ");
for (i = 1; i <= GetDaysofMonth(y, m); i++)
{
printf("%5d", i);
count++;
if (count % 7 == 0)
printf("\n");
}
if (count % 7 != 0)
printf("\n");
printf("***********************************");
}
重点
1.第一个循环负责打空格,这个要弄不明白,就举几个例子,count为0,不打空格,count是几就打几个空格。
2.日期打印
记住每打印七次七个就要换一次行,而且这个次数是包括前面的空格的!!!!
3.最后的if判断换行,因为如果最后一行日期正好是七个,那他在循环里会打印换行,而最后的***********直接打印就好,但如果最后一行日期不是七个,那你就要自己在打印换行,不然就会这样
很明显“*************”没换行
4.我还加了个循环,这样使用起来查找多个数据会更方便
#include
#include
int IsLeapYear(int y); /*判断是否闰年,细节不表*/
int GetDaysofMonth(int y, int m); /*确定某个月的天数,细节不表*/
int GetTotalDays(int y, int m); /*计算从1900年1月开始到给定年月间的天数,不包含给定月的天数,细节不表*/
int GetFirstDayInTable(int y, int m); /*计算给定年月的第一天在日历表中的位置,返回值为0对应Sun位置,返回值为6对应Sta位置,细节不表*/
void ShowDate(int y, int m); /*显示日历*/
int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int main()
{
printf("只限于查找1900年之后\n");
int y, m,x=1;
do
{
printf("查询日历输入1,结束程序输入0:->");
scanf("%d", &x);
if (x)
{
printf("输入查询年份月数");
scanf("%d%d", &y, &m);
ShowDate(y, m);
printf("\n");
}
else
return 0;
} while (x);
}
int IsLeapYear(int y) /*判断是否闰年,细节不表*/
{
if (!(y % 4) && y % 100 || !(y % 400))
return 1;
return 0;
}
int GetDaysofMonth(int y, int m)/*确定某个月的天数,细节不表*/
{
if (IsLeapYear(y) && m == 2)
return 29;
return month[m];
}
int GetTotalDays(int y, int m) /*计算从1900年1月开始到给定年月间的天数,不包含给定月的天数,细节不表*/
{
int sum = 0,i;
for ( i = 1900; i < y; i++)
{
sum = sum + 365 + IsLeapYear(i);
}
for (i = 1; i < m; i++)
sum += month[i];
if (IsLeapYear(y) && m > 2)
sum++;
return sum;
}
int GetFirstDayInTable(int y, int m)/*计算给定年月的第一天在日历表中的位置,返回值为0对应Sun位置,返回值为6对应Sta位置,细节不表*/
{
int sum= GetTotalDays(y, m);
sum %=7;
if (sum == 6)
return 0;
return sum+1;
}
void ShowDate(int y, int m)
{
printf("***********************************\n");
printf(" Sun Mon Tue Wen Thur Fri Sta\n");
int count = GetFirstDayInTable(y, m);
int i;
for (i = 0; i < count; i++)
printf(" ");
for (i = 1; i <= GetDaysofMonth(y, m); i++)
{
printf("%5d", i);
count++;
if (count % 7 == 0)
printf("\n");
}
/* if (count % 7 != 0)
printf("\n");*/
printf("***********************************");
}
感觉很多时候敲代码很多部分都可以找到一点又一点的小小的优化,找啊找代码就变简洁了
如果那里写错了希望在评论区提一下,我会尽快改的
如果你觉得有用就点个赞支持一下吧!谢谢啦