【C 语言之项目实战】判断闰年及计算天数(详细版)

本文介绍了一个C语言项目,实现包括判断闰年、计算月份天数及输入日期计算总天数的功能。项目包含四个主要函数:Is_Leap()用于判断闰年,Get_YM_Day()计算月份天数,Get_YMD_Total()计算日期总天数,以及主函数main()。项目使用静态常量数组和循环叠加方法,确保了代码的效率和准确性。在main()函数中,还包含了错误处理和用户交互功能,允许用户连续输入和检查日期。
摘要由CSDN通过智能技术生成

目录

1.项目要求
2.定义模块函数
3.各模块函数实现
4.项目源代码
5.项目总结

1. 项目要求

1.1 首先判断用户输入的年份是否为闰年;
1.2 计算一年中每个月份的天数;
1.3 用户输入日期(年月日),计算输出天数 。

2. 定义函数

2.1 主函数:main()
2.2 判断闰年函数:Is_Leap()
2.3 计算月份天数:Get_YM_day()
2.4 输入日期计算天数:Get_YMD_Total()

3. 各模块函数实现

3.1 判断闰年函数:Is_Leap()

     ①. 算法思想:闰年判断条件是,输入的任意年份满足能被 4 整除但不能被 100 整除或者满足能被 400 整除即可。

     ②. 源程序

/** 判断是否为闰年 */
bool Is_Leap(int year)
{
	/**
	bool leap;		// bool 类型初始值默认为 false
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
	{
		leap = true;
	}
	return leap;
	*/
	// 等价于 ==> 
	return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}

3.2 计算月份天数:Get_YM_day()

     ①. 算法思想:月份天数基本上是固定不变的,除了 2 月份,闰年 29 天,非闰年 28 天。所以采用数组实现,通过查表法,用户输入月份就可得到相应的天数。月份即为数组下标,因为数组下表是从 0 开始,所以下表 0 表示闰年的 2 月天数 29 天,下标 1 – 12 表示非闰年 1 - 12 月 对应的天数。

     ②. 源程序

/** 计算一年中月份的天数 Get_YM_day */
int Get_YM_Day(int year, int month)
{
	// 静态常性数组 static 只初始化一次 const 且只可读不可写
	// 主函数每调用一次 都会开辟一次数组空间 调用结束后释放空间 
	//  用 static 静态关键字 作用域在函数内部 生存期在数据区(.data)避免每次调用每次开辟空间
	static const int days[13] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	//							  0   1   2   3   4   5   6   7   8   9   10  11  12
	if (month == 2 && Is_Leap(year))
	{
		month = 0;
	}
	return days[month];
}

     ③. 总结:静态常性数组 static 只初始化一次,const 只可读不可写,主函数每调用一次都会开辟一次数组空间,调用结束后释放空间;用 static 静态关键字,作用域在函数内部,生存期在数据区(.data),避免每次调用每次开辟空间

     关键字详情请参考 《C语言之初识关键字》,点击此处即可阅读

3.3 输入日期计算天数:Get_YMD_Total()

     ①. 算法思想:循环叠加用户输入月份的前几个月的天数 + 当月的天数,如:用户输入 6 月 8 日 计算前 5 个月的天数 + 6 月的 8 天,最后还需判断用户输入的年月日是否正确。

/** 输出日期 计算天数 Get_YMD_Total */
int Get_YMD_Total(int year, int month, int day)
{
	// 循环叠加用户输入月份的前几个月的天数 + 当月的天数 如:用户输入 6 月 8 日 计算前 5 个月的天数 + 8 天
	int sum = 0;
	if (year < 1) return YEAR_ERROR;									// 输入的年份出错
	if (month < 1 || month > 12) return MONTH_ERROR;					// 输入的月份出错
	if (day < 1 || day > Get_YM_Day(year, month)) return DAY_ERROR;		// 输入的天数出错
	for (int i = 1; i < month; ++i)										// 累加求输入月份的前几个月的天数
	{
		sum += Get_YM_Day(year, i);										
	}
	sum += day;														 	// 加上当月天数
	return sum;
}

3.4 主函数:main()

/** 主函数 */
int main()
{
	int year, month, day, day1;
	char ch = '\0';
	do {
		printf("Input (year month day): \n");
		scanf_s("%d %d %d", &year, &month, &day);
		// 计算一年中月份的天数
		day1 = Get_YM_Day(year, month);
		// 输出日期 计算天数
		int total = Get_YMD_Total(year, month, day);
		switch (total)
		{
		case YEAR_ERROR:
			printf("year input error! \n");
			break;
		case MONTH_ERROR:
			printf("month input error! \n");
			break;
		case DAY_ERROR:
			printf("day input error! \n");
			break;
		default:
			if (Is_Leap(year)) 
			{
				printf("%d年是闰年!\n", year);
			}
			else
			{
				printf("%d年不是闰年!\n", year);
			}
			printf("%d年的%d月==>%d天\n", year, month, day1);
			printf("%d年%d月%d日==>%d天\n", year, month, day, total);
			break;
		}
		printf("是否继续(y/n)... \n");
		// 清除缓冲区 // fflush(stdin); 在 vs 2015 年之后就失效了
		// 清除缓冲区的作用:键盘录入时会有 ‘\n’ 为了避免 ‘\n’的干扰需清除缓冲区
		rewind(stdin);		
		ch = getchar();
	} while (ch == 'Y' || ch == 'y');
	return 0;
}

4. 项目源代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define YEAR_ERROR -1
#define MONTH_ERROR -2
#define DAY_ERROR -3

/** 项目:
* 判断是否为闰年 Is_Leap
* 计算一年中月份的天数 Get_YM_day
* 输出日期 计算天数 Get_YMD_Total
*/

/** 判断是否为闰年 */
bool Is_Leap(int year)
{
	return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}

/** 计算一年中月份的天数 Get_YM_day */
int Get_YM_Day(int year, int month)
{
	// 静态常性数组 static 只初始化一次 const 且只可读不可写
	static const int days[13] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	//							  0   1   2   3   4   5   6   7   8   9   10  11  12
	if (month == 2 && Is_Leap(year))
	{
		month = 0;
	}
	return days[month];
}

/** 输出日期 计算天数 Get_YMD_Total */
int Get_YMD_Total(int year, int month, int day)
{
	// 循环叠加用户输入月份的前几个月的天数 + 当月的天数 如:用户输入 6 月 8 日 计算前 5 个月的天数 + 8 天
	int sum = 0;
	if (year < 1) return YEAR_ERROR;									// 输入的年份出错
	if (month < 1 || month > 12) return MONTH_ERROR;					// 输入的月份出错
	if (day < 1 || day > Get_YM_Day(year, month)) return DAY_ERROR;		// 输入的天数出错
	for (int i = 1; i < month; ++i)
	{
		sum += Get_YM_Day(year, i);		
	}
	sum += day;
	return sum;
}

/** 主函数 */
int main()
{
	int year, month, day, day1;
	char ch = '\0';
	do {
		printf("Input (year month day): \n");
		scanf_s("%d %d %d", &year, &month, &day);
		// 计算一年中月份的天数
		day1 = Get_YM_Day(year, month);
		// 输出日期 计算天数
		int total = Get_YMD_Total(year, month, day);
		switch (total)
		{
		case YEAR_ERROR:
			printf("year input error! \n");
			break;
		case MONTH_ERROR:
			printf("month input error! \n");
			break;
		case DAY_ERROR:
			printf("day input error! \n");
			break;
		default:
			if (Is_Leap(year)) {
				printf("%d年是闰年!\n", year);
			}
			else
			{
				printf("%d年不是闰年!\n", year);
			}
			printf("%d年的%d月==>%d天\n", year, month, day1);
			printf("%d年%d月%d日==>%d天\n", year, month, day, total);
			break;
		}
		printf("是否继续(y/n)... \n");
		// 清除缓冲区 // fflush(stdin); 在 vs 2015 年之后就失效了
		// 清除缓冲区的作用:键盘录入时会有 ‘\n’ 为了避免 ‘\n’的干扰需清除缓冲区
		rewind(stdin);		
		ch = getchar();
	} while (ch == 'Y' || ch == 'y');
	return 0;
}

运行结果
在这里插入图片描述

5. 项目总结

     在做项目之前,先分析项目需求,设置完成项目实例所需要的各模块函数;思考各模块函数代码实现的算法思想,通过算法思想一步步完成各模块函数代码的实现并进行优化。通过调试逐步完善代码,最终实现项目实例代码的编写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值