fun.c文件
这段代码实现了一个日历打印功能,包含多个函数协同工作。下面对每个函数进行详细解释:
1. 判断闰年函数 isLeapyear
int isLeapyear(int year)
{
return year%4==0&&year%100!=0||year%400==0;
}
- 功能:判断一个年份是否为闰年
- 闰年规则:
- 能被4整除且不能被100整除,或者
- 能被400整除
- 返回值:如果是闰年返回1(真),否则返回0(假)
2. 获取月份天数函数 daysOfTheMonth
int daysOfTheMonth(int year,int month)
{
int a[]={31,0,31,30,31,30,31,31,30,31,30,31};
if(month<=0||month>=12)
{
return -1; // 月份无效返回-1
}
if(month!=2)
{
return a[month-1]; // 返回对应月份的天数(非2月)
}
else
{
return isLeapyear(year)?29:28; // 2月根据闰年判断28或29天
}
}
- 功能:计算指定年月的天数
- 实现:
- 用数组
a存储1-12月的天数(2月用0占位) - 先判断月份是否有效(1-12月)
- 非2月直接从数组获取天数
- 2月调用
isLeapyear判断是28天还是29天
- 用数组
- 返回值:月份天数,无效月份返回-1
3. 计算自1900年以来的总天数 daysAfter1900
int daysAfter1900(int year,int month)
{
int i;
int days;
int counter=0; // 计算闰年年数
// 计算1900年到目标年份前一年的总天数
for(i=1900;i<year;++i)
{
if(isLeapyear(i)!=0)
{
++counter; // 统计闰年数量
}
}
// 计算完整年份的总天数:闰年366天,平年365天
days=counter*366+(year-counter-1900)*365;
// 计算目标年份中,到目标月份前一个月的总天数
int j;
int days2=0;
int a[]={31,0,31,30,31,30,31,31,30,31,30,31};
for(j=0;j<month-1;++j)
{
days2+=a[j]; // 累加前几个月的天数
}
// 加上2月的天数(根据闰年调整)
if(isLeapyear(year)==1)
{
days2+=29;
}
else
{
days2+=28;
}
return days+days2; // 返回总天数
}
- 功能:计算从1900年到指定年月的总天数(不含当月天数)
- 实现步骤:
- 计算1900年到目标年份前一年的所有天数(区分闰年和平年)
- 计算目标年份中从1月到目标月份前一个月的总天数
- 累加两部分得到总天数
- 用途:为计算月份第一天是星期几提供基础
4. 计算月份第一天是星期几 weekOfTheFirstDay
int weekOfTheFirstDay(int year,int month)
{
int days;
days=daysAfter1900(year,month);
return (days+1)%7;
}
- 功能:计算指定年月的第一天是星期几
- 实现逻辑:
- 基于
daysAfter1900的结果(距离1900年的总天数) - 加1后对7取模(假设1900年1月1日是星期一)
- 基于
- 返回值:0表示星期日,1表示星期一,…,6表示星期六
5. 打印日历函数 printCalendar
void printCalendar(int year,int month)
{
char str[20];
sprintf(str,"%d",month);
printf(" %s月 %4d年\n",str,year); // 打印月份和年份标题
printf("日 一 二 三 四 五 六\n"); // 打印星期标题
int a[6][7] = {0}; // 用6行7列数组存储日历数据
int k, l = 0;
int days = daysOfTheMonth(year, month); // 获取当月总天数
int firstDay = weekOfTheFirstDay(year, month); // 当月第一天是星期几
// 填充第一行数据
for(k = 0; k < 7; ++k)
{
if(k < firstDay) {
a[0][k] = 0; // 月初前的位置填0
} else {
if(l < days) {
a[0][k] = ++l; // 填充日期
} else {
a[0][k] = 0;
}
}
}
// 填充剩余行
for(int i = 1; i < 6; ++i)
{
for(int j = 0; j < 7; ++j)
{
if(l < days) {
a[i][j] = ++l; // 继续填充日期
} else {
a[i][j] = 0; // 月末后的位置填0
}
}
if(l >= days) break; // 所有日期已填完则退出
}
// 打印日历
for(int o = 0; o < 6; ++o)
{
for(int p = 0; p < 7; ++p)
{
if(a[o][p] == 0) {
printf(" "); // 0值显示为三个空格
} else {
printf("%2d ", a[o][p]); // 日期格式化输出
}
}
printf("\n"); // 每行结束换行
}
printf("\n");
}
- 功能:打印指定年月的日历
- 实现步骤:
- 打印月份和年份标题,以及星期标题
- 创建6x7的二维数组存储日历数据(最多6行可容纳任何月份)
- 计算当月总天数和第一天是星期几
- 填充数组:
- 第一行从第一天对应的星期位置开始填充
- 后续行依次填充剩余日期
- 非日期位置填充0
- 打印数组:0值显示为空格,日期格式化输出保持对齐
整个程序通过这几个函数的协作,能够准确计算并打印出指定年月的日历,考虑了闰年、每月不同天数以及星期几的正确对应关系。
fun.h
extern int isLeapyear(int year);
extern int daysOfTheMonth(int year,int month);
extern int daysAfter1900(int year,int month);
extern int weekOfTheFirstDay(int year,int month);
extern int printCalendar(int year,int month);
total.c
#include<stdio.h>
#include"fun.h"
int main(void)
{
int year=2025;
int month=10;
// printf("%d\n",isLeapyear(year));
// printf("%d\n",daysAfter1900(year,month));
// printf("%d\n",weekOfTheFirstDay(year,month));
printCalendar(year,month);
return 0;
}
运行结果:

&spm=1001.2101.3001.5002&articleId=149653148&d=1&t=3&u=f15ab4b8987245f2beb4a8e1b0335c1b)
378

被折叠的 条评论
为什么被折叠?



