开篇
本篇文章的题目来源于《编程珠玑》第三章课后习题的第四个问题,也是我会手动实现的本章的最后一个功能。
问题概要
给定月和年,使用字符数组生成该月的日历(含有周几的日历)。
思路分析
为了生成给定年份中某个月的日历,我们需要知道该月有多少天(注意要正确处理二月份)以及该月的第一天是周几。
下面的代码相对来说比较简单,我不过多描述,不过有些细节需要说一下:
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公式的应用方面需要稍微注意一下。
希望本文对您有所帮助。
感谢阅读!