开篇
本篇文章的题目来源于《编程珠玑》第三章课后习题的第四个问题,也是我会手动实现的本章的最后一个功能。
问题概要
给定月和年,使用字符数组生成该月的日历(含有周几的日历)。
思路分析
为了生成给定年份中某个月的日历,我们需要知道该月有多少天(注意要正确处理二月份)以及该月的第一天是周几。
下面的代码相对来说比较简单,我不过多描述,不过有些细节需要说一下:
printf(" 一 二 三 四 五 六 日\n"); 在这行代码中,每个字前面是两个空格,因为每个大写的数字占据两个空格,加起来共计4个空格,和下面printf(“%4d”, day);对应;
printf(" “);这一句代码中每次打印的是四个空格,同时也和printf(”%4d", day);对应。
代码实现
#include <stdio.h>// 判断是否是闰年
int isLeapYear(int year) {return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}// 获取某年某月的天数
int getDaysOfMonth(int year, int month) {if (month == 2) {return isLeapYear(year) ? 29 : 28;}else if (month == 4 || month == 6 || month == 9 || month == 11){return 30;}else {return 31;}
}// 获取某年某月的第一天是周几(0代表周日)
int getFirstDayOfWeek(int year, int month) {// Zeller公式if (month < 3) {month += 12;year--;}int h = (1 + (13 * (month + 1)) / 5 + year + year / 4 - year / 100 + year / 400) % 7;return (h + 5) % 7; // 转换成以星期一为起始的表示方式return h;
}// 打印日历
void printCalendar(int year, int month) {int daysOfMonth = getDaysOfMonth(year, month);int firstDaysOfWeek = getFirstDayOfWeek(year, month);printf(" 一 二 三 四 五 六 日\n");for (int i = 0; i < firstDaysOfWeek; i++) {printf(" ");}// 打印日历for (int day = 1; day <= daysOfMonth; day++) {printf("%4d", day);// 换行if ((firstDaysOfWeek + day) % 7 == 0 || day == daysOfMonth) {printf("\n");}}
}int main() {int year, month;printf("请输入年份: ");scanf_s("%d", &year);printf("请输入月份: ");scanf_s("%d", &month);printf("\n%d年%d月日历: \n", year, month);printCalendar(year, month);return 0;
}
效果展示
注
这段代码相对来说较为简单,也就Zeller公式的应用方面需要稍微注意一下。
希望本文对您有所帮助。
感谢阅读!