有我自己的注释与思考,希望可以帮助到有需要的朋友。若有错误,麻烦提醒更正。
已知,1900年的一月一号是周一,由此来求出你输入的任意一年的 12个月 的日历。
/*注释1.:平年365天,即52周余一天,闰年366天,即52周余二天。即:从x年到1900年,每个平年都在52周基础上多一天,每个闰年都在52周基础上多两天。所以可以推理出,每过一个平年都相比1900年多出1天,每过一个个闰年都多出两天。所以,可以看成:若是过了n年,则至少多出了n天,中间有m个闰年,就再多加m天。*/
/*注释2.:任意两个日期间。若是正好隔了k周(k为整数),则两个日期一定都是礼拜一或都
已知,1900年的一月一号是周一,由此来求出你输入的任意一年的 12个月 的日历。
/*注释1.:平年365天,即52周余一天,闰年366天,即52周余二天。即:从x年到1900年,每个平年都在52周基础上多一天,每个闰年都在52周基础上多两天。所以可以推理出,每过一个平年都相比1900年多出1天,每过一个个闰年都多出两天。所以,可以看成:若是过了n年,则至少多出了n天,中间有m个闰年,就再多加m天。*/
/*注释2.:任意两个日期间。若是正好隔了k周(k为整数),则两个日期一定都是礼拜一或都
是礼拜二或都是礼拜三、四、五、六、日 。所以只要求出x年第一天相比1900年一月一日是周一多了(n+m)天,就可以求出 x年的一月一日是周e。e=(n+m+1)%7. (因为1900年一月一日是周一,所以要在此基础上计算,得+1哦~)*/
下面贴上代码
#include<stdio.h>
int isleep(int year){ /*函数目的:判断是否是闰年,因为闰年2月有29天。*/
int leep=0;
if(year%4==0 && year%100 || year%400==0)
leep=1;
return leep;
}
int week_of_firstday(int year){ /*函数目的:求出每年第一天,是周几。*/
int n=year-1900; //求出今年与1900年相差多少年。
n=n+(n-1)/4; //闰年个数,为(n-1)/4,再根据“注释1”与“注释2”可求出总共多出了n天。
n=(n+1)%7; //(n+1)%7,在多出的n天基础上,在求出这n天不足一周有几天。
return n;
}
int len_of_month(int year,int month){ /*函数目的:返回year年的month月有多少天。*/
int daynumber;
if(month==4||month==6||month==9||month==11)
daynumber=30;
else if(month==2)
if(isleep(year))
daynumber=29;
else daynumber=28;
else daynumber=31;
return daynumber;
}
int main (void)
{
int year,month,day,weekday,days_of_month,i;
printf("你想求出哪一年的日历?\n请输入年份:");
scanf("%d",&year);
printf("\n\n\t\t%d",year);
weekday=week_of_firstday(year); //调用 week_of_firstday(),得到返回值付给 weekday,可以求出本年度第一天是周几 。
for(month=1;month<=12;month++)
{ //循环12次,求出每个月的日历
printf("\n\t\t%d月\n",month);
printf(" ---------------------------------\n");
printf(" SUN MON TUE WED THU FRI SAT\n");
printf(" ---------------------------------\n");
for(i=0;i<weekday;i++)
printf(" "); //每个月都要 从 周weekday 开始输出日期,weekday之前输出空格。
days_of_month=len_of_month(year,month); // 求每个月的天数。
for(day=1;day<=days_of_month;day++)
{
printf("%5d",day);
weekday=(weekday+1)%7; //每循环一次,weekday+1;,通过余数控制weekday不超过7。
if(weekday==0)
printf("\n"); //若是weekday将周六的日期输出后,+1后等于7了,则换行。输出 周日 的日期。
} //然后继续循环,输出 周一 的日期........
}
return 0;
}
代码可以直接运行。但我只考虑了1900年到2100年之间的,没有试过2100年之后的是否正确。因为1900年就挺特殊的。2100年和它性质相似。(2096是润年,2100年不是闰年,2104年是润年,也即相差了8年才有一闰)
改的话,是在 week_of_firstday() 这个函数中进行修改。加两个条件判断条件应当就可以了。