C++实现万年历(附代码)

本文详细介绍了如何使用C++编写一个万年历程序,包括闰年的判断方法、每月天数计算以及根据用户选择输出年份或月份的详细步骤。通过模块化设计,将复杂问题分解为RUN、MD、YFD、MFD和Print_1/2等函数。
摘要由CSDN通过智能技术生成

本文给大家介绍如何使用C++语言解决万年历问题,笔者尽量做到讲解过程简单、细致,让读者可以轻松阅读。

正文开始:

目录

前提知识

1.闰年的判断方法

2.每年、月的时长

3.公元1年的第一天是星期一

讲解

函数说明

代码讲解

主函数

(1)RUN:计算当年是否是闰年

(2)MD:计算当月的天数

(3)YFD:计算当年第一天是星期几

(4)MFD:当月第一天是星期几

(5)Print_1:打印选择1的万年历 

(6)Print_2:打印选择2的万年历

完整代码


前提知识

1.闰年的判断方法

普通闰年:公历年份是4的倍数,且不是100的倍数,为闰年。

世纪闰年:公历年份是400的倍数也是闰年。

其他为平年。

2.每年、月的时长

平年一年365天。每月天数分别为{ 31,28,31,30,31,30,31,31,30,31,30,31 }。

闰年二月多一天,为29天,一年366天。

3.公元1年的第一天是星期一

讲解

笔者讲解的万年历问题有两种输入输出类型,按年输出or按月输出。

根据模块化程序设计思想,我们把万年历问题分为计算天数和输出两个部分。

借助函数我们可以将复杂的问题分解为小问题分别解决。

函数说明

分多个模块进行:

(1)RUN:计算当年是否是闰年

(2)MD:MonthDay,计算当月的天数,函数名简写为MD

(3)YFD:YearFirstDay,计算当年第一天是星期几,简写为YFD

(4)MFD:MonthFirstDay,计算当月第一天是星期几,简写为MFD

(5)Print:根据当月天数打印万年历  i)Print_1:打印选择1的万年历  ii)Print_2:打印选择2的万年历

代码讲解

主函数

先输出提示内容。

cout << "万年历显示程序" << endl;
cout << "***********************" << endl;
cout << "1   按年输出" << endl << "2   按月输出" << endl << "0   退出" << endl;
cout << "***********************" << endl;

根据输入,输出不同类的万年历或退出。 

for (int i = 1;;i++)
{
	cout << "万年历 " << i << " :" << endl;
	cout << "请输入您的选择" ;
	int choice;
	cin >> choice;
	if (choice == 1)
	{
		cout << "请输入显示的年份" ;
		int year;
		cin >> year;
		Print_1(year);
	}
	else if (choice == 2)
	{
		int year, month;
		cout << "请输入显示的年份" ;
		cin >> year;
		cout << "月份" ;
		cin >> month;
		Print_2(year, month);
	}
	else if (choice == 0)
	{
		cout << "程序结束!" << endl;
		break;
	}
	cout << endl;
}

以上只是简单的输入与函数调用。for循环是为了有多次输入与输出,直至输入0,结束。 

(1)RUN:计算当年是否是闰年

根据闰年规则,我们可以容易地写出函数RUN

bool RUN(int year)
{
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
		return 1;
	else
		return 0;
}
(2)MD:计算当月的天数

月份为2月时,根据闰年判断输出天数。不是二月时,直接输出当月天数即可。

int MD(int year, int month)
{
	int a[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2)
	{
		if (RUN(year))
			return a[1] + 1;
		else
			return a[1];
	}
	else
	{
		return a[month - 1];
	}
}

 这里笔者用数组记载每月天数。读者也可以用switch-case结构来输出。

(3)YFD:计算当年第一天是星期几

根据公元1年的第一天是星期一,笔者用函数递归的方法解决这个问题:

今年第一天星期数是(去年第一天星期数+去年全年天数)%7

int YFD(int year)//输出结果为 0-6(0表示星期天)
{
	if (year == 1)
		return 1;
	else
	{
		if (RUN(year - 1))
			return (YFD(year - 1) + 366) % 7;
		else
			return (YFD(year - 1) + 365) % 7;
	}
}
(4)MFD:当月第一天是星期几

类似上一个函数,运用函数递归:

这个月第一天星期数是(上个月第一天星期数+上个月天数)%7

注意:函数形参不仅仅是月份,因为每月天数要根据年份用MD函数计算。

int MFD(int year, int month)
{
	if (month == 1)
		return YFD(year);
	else
		return (MFD(year, month - 1) + MD(year, month - 1)) % 7;
}
(5)Print_1:打印选择1的万年历 
void Print_1(int year)
{
	for (int j = 1;j <= 12;j++)
	{
		cout << "  " << j << "月" << endl;
		Print_2(year,j);
	}
}
(6)Print_2:打印选择2的万年历

首先输出头表,"  日  一  二  三  四  五  六"。

获取第一天的星期数和该月天数。

输出第一天时,与星期数对齐,之后的天数依次输出。

这里需要一个用于换行的标志pos,用于记载每个数的位置,一旦到达末尾要换行。

void Print_2(int year, int month)
{
	cout << "  日  一  二  三  四  五  六" << endl;
	int pos = MFD(year, month), day = MD(year, month);
	cout << setw(4 * pos + 4) << 1;
	pos++;
	if (pos == 7)
	{
		cout << endl;
		pos = 0;
	}
	for (int i = 2;i <= day;i++)
	{
		cout << setw(4) << i;
		pos++;
		if (pos == 7)
		{
			cout << endl;
			pos = 0;
		}
	}
	cout << endl;
}

完整代码

#include<iostream>
#include<iomanip>
using namespace std;
bool RUN(int year);
int MD(int year, int month);
int YFD(int year);
int MFD(int year, int month);
void Print_1(int year);
void Print_2(int year, int month);

bool RUN(int year)
{
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
		return 1;
	else
		return 0;
}
int MD(int year, int month)
{
	int a[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2)
	{
		if (RUN(year))
			return a[1] + 1;
		else
			return a[1];
	}
	else
	{
		return a[month - 1];
	}
}
int YFD(int year)//输出结果为 0-6(0表示星期天)
{
	//用函数递归解决
	//今年第一天星期数是(去年第一天星期数+去年全年天数)%7
	if (year == 1)
		return 1;
	else
	{
		if (RUN(year - 1))
			return (YFD(year - 1) + 366) % 7;
		else
			return (YFD(year - 1) + 365) % 7;
	}
}

int MFD(int year, int month)
{
	//递归
	//这个月第一天星期数是(上个月第一天星期数+上个月天数)%7
	if (month == 1)
		return YFD(year);
	else
		return (MFD(year, month - 1) + MD(year, month - 1)) % 7;
}
void Print_1(int year)
{
	for (int j = 1;j <= 12;j++)
	{
		cout << "  " << j << "月" << endl;
		Print_2(year,j);
	}
}
void Print_2(int year, int month)
{
	cout << "  日  一  二  三  四  五  六" << endl;
	int pos = MFD(year, month), day = MD(year, month);
	cout << setw(4 * pos + 4) << 1;
	pos++;
	if (pos == 7)
	{
		cout << endl;
		pos = 0;
	}
	for (int i = 2;i <= day;i++)
	{
		cout << setw(4) << i;
		pos++;
		if (pos == 7)
		{
			cout << endl;
			pos = 0;
		}
	}
	cout << endl;
}
int main()
{
	cout << "万年历显示程序" << endl;
	cout << "***********************" << endl;
	cout << "1   按年输出" << endl << "2   按月输出" << endl << "0   退出" << endl;
	cout << "***********************" << endl;
	for (int i = 1;;i++)
	{
		cout << "万年历 " << i << " :" << endl;
		cout << "请输入您的选择" ;
		int choice;
		cin >> choice;
		if (choice == 1)
		{
			cout << "请输入显示的年份" ;
			int year;
			cin >> year;
			Print_1(year);
		}
		else if (choice == 2)
		{
			int year, month;
			cout << "请输入显示的年份" ;
			cin >> year;
			cout << "月份" ;
			cin >> month;
			Print_2(year, month);
		}
		else if (choice == 0)
		{
			cout << "程序结束!" << endl;
			break;
		}
		cout << endl;
	}
	return 0;
}

测试结果

  • 25
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值