c语言编程显示单月日历,任意年月日历输出-题解(C语言代码)

本题目主要解决如下几个问题:

**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 人评分

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值