本题目主要解决如下几个问题:
**1、该月的1号是星期几;
2、该月份有几天;
3、2月份天数的特殊处理;
4、输出格式问题。**
我们来一次解决如上问题:
###### 问题1:该月的1号是星期几
我们知道星期几是以7天作为循环周期的,我们分别用**0~6**这几个数字,分别代表星期天到星期六。
![](/image_editor_upload/20191003101309_54683.jpg)
为此我们可以用**余数**的方法来求得第k天后是星期几。
我们先用简单的来计算一下,现已知**今天是星期天**,第k天后是星期几,我们可以观察下图,得出一个规律:第k天后是星期**k%7**(如果是0代表星期天)
![](/image_editor_upload/20191003103259_89072.jpg)
题目给的已知条件是星期一,现要求第k天是星期几,这里的k是2007/1/1到所要求的XXXX年XX月1日的总天数,为此我们得到
第k天后是星期**(k-(7-1))%7**,这里的1是指星期一所对应序号1,因为我们是从星期一开始计算的,而减去(7-1)是为了把初始值变成星期天,方便计算。
通过余数的计算我们把(k-(7-1))%7化简一下:
( k - (7-1))%7
=( k - 7 + 1 )%7
=( k%7 - 7%7 + 1%7 )%7
=**( k%7 + 1)%7**
(只要知道总天数,代入该式就可求出XXXX年XX月1日是星期几)
###### 问题2:该月份有几天
我们可以用一个数组来记录每月有几天,需要时在调用。
`static int MonthDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };`
以365天的来算,其中数组下标表示对应的月份,下标0对应的月份做特殊处理,遇到闰年再把MonthDay[2]加一即可。
###### 问题3:2月份天数的特殊处理
其实也就是判断某年是否为闰年的问题,比较简单,代码如下:
```c
int CnkLeapYear( int year )
{
//能被4整除但不能被100整除或者能被400整除的年份即为闰年
if( ( (year % 4 == 0) && (year % 100 != 0) ) || ( year % 4 == 0 ) )
return 1;
else
return 0;
}
```
###### 问题4:输出格式问题
查看样例输出,可以看出,每一个星期几对应3个空格,即用%3d的格式输出。
每次输出星期6之后,就要输出\n,但这里需要注意一个问题,即最后输出“---------------------”前也要输出一个\n,即以下代码输出最后一行:
```c
printf("\n---------------------\n");
```
这会导致该月份最后一天是星期6这种特殊情况,而输出多一个\n,例如2015年2月。
所以用if语句判断最后一行前面的\n的输出情况。
完整代码如下:
```c
/***************************************
已知:2007年1月1日为星期一
要求:输出XXXX年X月所对应的公历表,其中XXXX大于等于2007
例子:2010年9月的日历如下
---------------------
Su Mo Tu We Th Fr Sa
---------------------
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
---------------------
>>>>>>> 需解决的问题 <<<<<<<
1、X月的1号是星期几;
2、该月份有几天;
3、2月份天数的特殊处理;
4、输出格式问题。
***************************************/
#include"stdio.h"
//每月的天数,以365天的来算,其中数组下标表示对应的月份,下标0对应的月份做特殊处理
static int MonthDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/**** 闰年判断函数 ****/
int CnkLeapYear( int year )
{
//能被4整除但不能被100整除或者能被400整除的年份即为闰年
if( ( (year % 4 == 0) && (year % 100 != 0) ) || ( year % 4 == 0 ) )
return 1;
else
return 0;
}
/**** 获取星期几的函数 ****/
int GetWeek_day( int year, int month )
{
int week_day;
int sum_day = 0; //2007年1月1日距离所求月份的1号有几天
/*** 求出year前与2007年之间的天数和***/
for( int i = 2007; i < year; i++) {
if( 1 == CnkLeapYear( i ) )
sum_day += 366;
else
sum_day += 365;
}
/*** 求出在year的month前的天数和 ***/
if( ( 1 == CnkLeapYear( year ) ) && ( month > 2 ) ) {
/***** >>>>> 注意!! 这里MonthDay[2]的2月份会根据是否为闰年加一 <<<<
0.0分
18 人评分