转载于我的博客园:https://www.cnblogs.com/xiao-qi-w/p/12997406.html
最近帮朋友做一些C语言的练习题,期间遇到了个比较有意思的题目,意在考察模块化程序设计,大致要求如下:
电子万年历:
1、编写函数int isleapyear(int year);判某年是否为闰年,如该年为闰年返回1,否则返回0。编写主函数输入年份给出该年是否为闰年。
2、编写函数int dayofmonth(int year ,int month);计算某年某月有几天。主函数中输入任意的年和月,给出此年该月有几天。
3、编写万年历。请利用上述1、2已编写的函数和下边已提供的函数来完成:
(1)输入年打印出此年的日历。
(2)输入年和月打印给出此年该月的日历。
/*参考代码*/
int firstdayofyear(int year) /*求某年的第一天是星期几*/
{
int i;
long n,days=year;
days=days*365; /* printf("\n%ld",days);*/
for(i=1; i
这道题并不算困难(给出了一些参考代码),而且根据上面给出的要求也不难得到如下思路:
第一问:根据闰年计算的规则编写一个闰年判断函数。
这里我采用的是格里高利闰年规则:
1.公元年份非4的倍数,为平年。
2.公元年份为4的倍数但非100的倍数,为闰年。
3.公元年份为100的倍数但非400的倍数,为平年。
4.公元年份为400的倍数,为闰年。
转换为C语言代码形式就成了下面这样子:
int isLeapyear(int year)
{//判断否为闰年
//满足上述规则2或4,返回1,否则返回0
return ((year%100!=0&&year%4==0) || year%400==0) ? 1 : 0;
}
第二问:编写函数计算某年某月有几天。
由于每一年的天数差别只在二月,而二月份天数的多少又受闰年的影响,所以我们只需要对二月进行特殊判断即可。可以利用第一问已经写过的函数,完成第二问,代码如下:
int dayOfMonth(int year, int month)
{//计算某年某月的天数
int x;//天数
switch(month){
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
x=31;
break;
case 2:
//闰年2月29天,平年28天
x=isLeapyear(year) ? 29 : 28;
break;
case 4:case 6:case 9:case 11:
x=30;
break;
default: break;
}
return x;
}
第三问:利用已知函数,根据输入打印出相应的年或月的日历。
重点在于第一小问,只要我们能正确输出某一月的日历,那么输出某年的日历就相当于依次输出1~12月的日历。参考代码中已经给出了两个非常有用的函数,分别是:
这里我的想法是先利用firstdayofmonth这个函数计算出某年某月第一天是星期几,然后计算出该月有多少天,最后利用循环输出,为了美观每七天换行一次。代码如下:
void displayMonth(int year, int month)
{
int start,days;//该月第一天是周几 该月的天数
start=firstdayofmonth(year,month);
days=dayOfMonth(year,month);
if(start==0)//如果等于零说明第一天刚好是星期天,要转换一下
start=7;
printf("一\t二\t三\t四\t五\t六\t日\n");
for(int i=1;i
第二小问就简单了,循环依次打印每月的日历就是某年的日历,代码如下:
void displayYear(int year)
{
for(int i=1;i<=12;++i){//循环调用打印月份的函数输出某年的日历
printf("%d月:\n",i);
displayMonth(year,i);
printf("\n");
}
}
最后把他们整合到成一个程序,代码如下:
#include
/**
* 目前使用的格里高利历闰年规则如下:
* 1.公元年份非4的倍数,为平年。
* 2.公元年份为4的倍数但非100的倍数,为闰年。
* 3.公元年份为100的倍数但非400的倍数,为平年。
* 4.公元年份为400的倍数,为闰年。
*/
//函数声明
int isLeapyear(int year); //判断是否为闰年
int dayOfMonth(int year, int month); //计算某年某月的天数
int firstdayofyear(int year); //求某年的第一天是星期几
int firstdayofmonth(int year, int month);//求某年某月的第一天是星期几
void displayYear(int year); //打印某年的日历
void displayMonth(int year, int month); //打印某年某月的日历
int main()
{
int year,month;
printf("请依次输入年份和月份:\n");
scanf("%d%d",&year,&month);
if(year<=0 || month<1 || month>12)
printf("输入不合法!");
else{
if(isLeapyear(year))
printf("是闰年,该月有%d天",dayOfMonth(year, month));
else
printf("是平年,该月有%d天",dayOfMonth(year, month));
printf("\n%d年的日历如下:\n",year);
displayYear(year);
printf("%d年%d月的日历如下:\n",year,month);
displayMonth(year,month);
}
return 0;
}
int isLeapyear(int year)
{//判断否为闰年
//满足上述规则2或4,返回1,否则返回0
return ((year%100!=0&&year%4==0) || year%400==0) ? 1 : 0;
}
int dayOfMonth(int year, int month)
{//计算某年某月的天数
int x;//天数
switch(month){
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
x=31;
break;
case 2:
//闰年2月29天,平年28天
x=isLeapyear(year) ? 29 : 28;
break;
case 4:case 6:case 9:case 11:
x=30;
break;
default: break;
}
return x;
}
int firstdayofyear(int year)
{//求某年的第一天是星期几
long days; //天数
days=year*365;//从0年到year年一共有多少天
for(int i=1;i
运行效果见下图(根据可需要在主函数修改输出内容):
虽然说是万年历,但实际有点过于简单了(只显示公历),而且这个输入范围也有限制(不能超过int的范围),不过还是有点参考价值的。如果对你有帮助的话不妨支持一下,非常感谢