c语言课程设计之桌面日历(完整源码+注释)

为了应付c语言课程设计,挑了个简单的题目随便写了写

 

题目描述:

桌面日历

1) 按照输入的年份,显示这一年每月日历。

2) 按照输入的年份和月份,显示这个月的日历。

3)显示当月的日历。

日历显示形式同挂历。

用到的知识点:

函数、简单的函数调用、简单的逻辑关系

实现功能演示:

主界面:

功能一:

 

功能二:

功能三:

 完整代码

#include <stdio.h>
#include <time.h>
// 判断是否为闰年函数
int isLeapYear(int);
// 判断某年某月的第一天是周几的函数
int daysWeek(int, int);
// 判断月份有几天函数
int monthDays(int, int);
// 输出某年某月日历函数
void monthCalendar(int, int);
int main()
{
    int Year, Month;
    // 模式选择
    int mode;
    printf("-----------------------------------------\n");
    printf("|               简易日历                |\n");
    printf("-----------------------------------------\n");
    printf("|     (1) 输入年份打印出全年历          |\n");
    printf("-----------------------------------------\n");
    printf("|     (2) 输入年份月份打印出月日历      |\n");
    printf("-----------------------------------------\n");
    printf("|     (3) 打印出当前月的日历            |\n");
    printf("-----------------------------------------\n");
    printf("|    请输入数字1 2 3以选择要使用的功能  |\n");
    printf("-----------------------------------------\n");
    printf("输入数字:");
    scanf("%d", &mode);
    printf("\n");
    if (mode == 1)
    {
        // 实现第一个功能
        printf("请输入年份: ");
        scanf("%d", &Year);
        // 从1遍历到12月 代表1月到十二月
        for (int i = 1; i <= 12; i++)
        {
            printf("--------------------------------------------------\n");
            printf("%d 年 %d 月\n", Year, i);
            monthCalendar(Year, i);
        }
    }
    else if (mode == 2)
    {
        // 实现第二个功能
        printf("请输入年份: ");
        scanf("%d", &Year);
        printf("请输入月份: ");
        scanf("%d", &Month);
        monthCalendar(Year, Month);
    }
    else if (mode == 3)
    {
        // 固定格式
        time_t timep;
        struct tm *p;
        time(&timep);
        p = gmtime(&timep);
        //获取当前年份,从1900开始,所以要加1900
        Year = 1900 + p->tm_year;
        //获取当前月份,范围是0-11,所以要加1
        Month = 1 + p->tm_mon;
        printf("当前时间为:%d年%d月\n", Year, Month);
        printf("--------------------------------------------------\n");
        printf("%d 年 %d 月\n", Year, Month);
        monthCalendar(Year, Month);
    }
    else
    {
        printf("请输入数字1 2 3选择功能 输入其他字符无效!");
    }

    return 0;
}
// 判断是否为闰年
int isLeapYear(int Year)
{
    // 如果能整除4且不能整除100或能整除400,则为闰年
    if (Year % 4 == 0 && Year % 100 != 0 || Year % 400 == 0)
    {
        return 1;
    }
    return 0;
}
// 判断月份有几天
int monthDays(int Year, int Month)
{
    // 如果月份为1、3、5、7、8、10、12 天数为31天
    if (Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12)
    {
        return 31;
    }
    // 如果月份为4、6、9、11 天数为30天
    else if (Month == 4 || Month == 6 || Month == 9 || Month == 11)
    {
        return 30;
    }
    else
    {
        // 月份为2月 如果是闰年 天数为29天
        if (isLeapYear(Year))
        {
            return 29;
        }
        // 如果不是闰年 天数为28天
        return 28;
    }
}
// 判断某年某月的第一天是周几
int daysWeek(int Year, int Month)
{
    // day用于记录总天数
    // day1记录每月的天数,结合下面代码理解
    int day = 0, day1 = 0;
    // 得到从1900年到某年的天数
    /**
     * @brief
     * 由于1900年1月1日为周一 得到1900年到某年的天数之后
     * 只需要用天数取7的余数,余数即是某年1月1日的周几
     * 所以也可以换为其他1月1日为周一的年份,使用1900年
     * 后,只能判断出1900年之后的年份
     */
    for (int i = 1900; i < Year; i++)
    {
        // 判断闰年
        if (isLeapYear(i))
        {
            day = day + 366;
        }
        else
        {
            day = day + 365;
        }
    }
    //判断月份
    for (int m = 1; m <= Month; m++)
    {
        day1 = monthDays(Year, m);
        if (m < Month)
        {
            // 计算天数
            day = day + day1;
        }
    }
    // week为某年某月第一天的周几
    int week = day % 7;
    return week;
}
// 具体实现打印某年某月日历
void monthCalendar(int Year, int Month)
{
    printf("--------------------------------------------------\n");
    printf("一\t二\t三\t四\t五\t六\t日\n");
    //判断这个月的第一天是星期几
    int t = daysWeek(Year, Month);
    // 判断月份有几天
    int day1 = monthDays(Year, Month);
    for (int i = 0; i < t; i++)
    {
        printf("\t");
    }
    //控制输出格式
    for (int i = 1; i <= day1; i++)
    {
        printf("%d\t", i);
        if ((i + t) % 7 == 0)
        {
            printf("\n");
        }
    }
    printf("\n");
    printf("--------------------------------------------------\n");
    printf("\n");
}

代码详解

大体思路:

功能的核心在于打印出某年中某月的日历,要想实现这个功能,需要知道:

这个月一共有几天、这个月的第一天是星期几

找到月份的天数思路:

首先判断月份,如果月份为1、3、5、7、8、10、12 天数为31天,如果月份为4、6、9、11 天数为30天,月份为2月时,如果年份是闰年,天数为29天,不是闰年天数为28天

判断月份第一天是周几思路:

首先要找一个1月1日为周一的年份,这里选用1900年举例

假如现在需要找到2022年9月份的第一天是周几

就需要得到1900年到2022年的总天数,总天数 = 整年数 × 年份天数 + 整月数 × 月份天数

也就是(2022-1900)× 年份天数(闰年366 平年365) + 8(要算9月份的日历,整月数为8) × 月份天数

然后再用总天数取7的余数,就是9月份一号的周几

表达能力有限,看不懂可以百度一下

代码详解:

判断闰年函数

如果一个年份可以整除4且不能整除100 或者可以整除400,则为闰年

int isLeapYear(int Year)
{
    if (Year % 4 == 0 && Year % 100 != 0 || Year % 400 == 0)
    {
        return 1;
    }
    return 0;
}

判断每月天数函数

如果月份为1、3、5、7、8、10、12 天数为31天

如果月份为4、6、9、11 天数为30天

月份为2月 如果是闰年 天数为29天 否则为28天

int monthDays(int Year, int Month)
{
    if (Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12)
    {
        return 31;
    }
    else if (Month == 4 || Month == 6 || Month == 9 || Month == 11)
    {
        return 30;
    }
    else
    {
        if (isLeapYear(Year))
        {
            return 29;
        }
        return 28;
    }
}

 判断某年某月的第一天是周几函数

结合着注释和上面解释

int daysWeek(int Year, int Month)
{
    // day用于记录总天数
    // day1记录每月的天数,结合下面代码理解
    int day = 0, day1 = 0;
    // 得到从1900年到某年的天数
    /**
     * @brief
     * 由于1900年1月1日为周一 得到1900年到某年的天数之后
     * 只需要用天数取7的余数,余数即是某年1月1日的周几
     * 所以也可以换为其他1月1日为周一的年份,使用1900年
     * 后,只能判断出1900年之后的年份
     */
    for (int i = 1900; i < Year; i++)
    {
        // 判断闰年
        if (isLeapYear(i))
        {
            day = day + 366;
        }
        else
        {
            day = day + 365;
        }
    }
    printf("整年天数%d",day);
    //判断月份
    for (int m = 1; m <= Month; m++)
    {
        day1 = monthDays(Year, m);
        if (m < Month)
        {
            // 计算天数
            day = day + day1;
        }
    }
    // week为某年某月第一天的周几
    printf("月份天数%d",day);
    int week = day % 7;
    return week;
}

具体实现打印函数

调用上面写好的函数

void monthCalendar(int Year, int Month)
{
    printf("--------------------------------------------------\n");
    printf("一\t二\t三\t四\t五\t六\t日\n");
    //判断这个月的第一天是星期几
    int t = daysWeek(Year, Month);
    // 判断月份有几天
    int day1 = monthDays(Year, Month);
    for (int i = 0; i < t; i++)
    {
        printf("\t");
    }
    //控制输出格式
    for (int i = 1; i <= day1; i++)
    {
        printf("%d\t", i);
        if ((i + t) % 7 == 0)
        {
            printf("\n");
        }
    }
    printf("\n");
    printf("--------------------------------------------------\n");
    printf("\n");
}

主函数

声明一个变量mode,用于功能的选择,将不同的功能写到不同的if语句中

其中获取当前系统时间的代码为固定格式,详细可以看这篇文章

C语言获取当前的日期及时间_Coder802的博客-CSDN博客_c 获取时间

功能一(全年历)的实现:写一个for循环 从1遍历到12,调用12次写好的函数

功能二(月份日历):输入年份和月份 调用函数

功能三(当前月日历):获取系统时间年份和月份,作为参数调用函数

int main()
{
    int Year, Month;
    // 模式选择
    int mode;
    printf("-----------------------------------------\n");
    printf("|               简易日历                |\n");
    printf("-----------------------------------------\n");
    printf("|     (1) 输入年份打印出全年历          |\n");
    printf("-----------------------------------------\n");
    printf("|     (2) 输入年份月份打印出月日历      |\n");
    printf("-----------------------------------------\n");
    printf("|     (3) 打印出当前月的日历            |\n");
    printf("-----------------------------------------\n");
    printf("|    请输入数字1 2 3以选择要使用的功能  |\n");
    printf("-----------------------------------------\n");
    printf("输入数字:");
    scanf("%d", &mode);
    printf("\n");
    if (mode == 1)
    {
        // 实现第一个功能
        printf("请输入年份: ");
        scanf("%d", &Year);
        // 从1遍历到12月 代表1月到十二月
        for (int i = 1; i <= 12; i++)
        {
            printf("--------------------------------------------------\n");
            printf("%d 年 %d 月\n", Year, i);
            monthCalendar(Year, i);
        }
    }
    else if (mode == 2)
    {
        // 实现第二个功能
        printf("请输入年份: ");
        scanf("%d", &Year);
        printf("请输入月份: ");
        scanf("%d", &Month);
        monthCalendar(Year, Month);
    }
    else if (mode == 3)
    {
        // 固定格式
        time_t timep;
        struct tm *p;
        time(&timep);
        p = gmtime(&timep);
        //获取当前年份,从1900开始,所以要加1900
        Year = 1900 + p->tm_year;
        //获取当前月份,范围是0-11,所以要加1
        Month = 1 + p->tm_mon;
        printf("当前时间为:%d年%d月\n", Year, Month);
        printf("--------------------------------------------------\n");
        printf("%d 年 %d 月\n", Year, Month);
        monthCalendar(Year, Month);
    }
    else
    {
        printf("请输入数字1 2 3选择功能 输入其他字符无效!");
    }

    return 0;
}

表达能力不佳,代码写的比较捞,有什么看不懂的地方可以私聊我,看到都会回的~~~

 

  • 47
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值