《C语言的科学与艺术》学习笔记之万年历代码

万年历算法:根据具体的某一天的真实日期及星期为基点,往前往后运算。 

 

#include <stdio.h>
#include <genlib.h>
#include <simpio.h>

#define Sunday    0
#define Monday    1
#define Tuesday   2
#define Wednesday 3
#define Thursday  4
#define Friday    5
#define Saturday  6

void GiveInstructions(void);
int GetYearFromUser(void);
void PrintCalendar(int year);
void PrintCalendarMonth(int month,int year);
void IndentFirstLine(int weekday);
int MonthDays(int month,int year);
int FirstDayOfMonth(int month,int year);
string MonthName(int month);
bool IsLeapYear(int year);

//主函数
main()
{
 int year;

 GiveInstructions();
 year=GetYearFromUser();
 PrintCalendar(year);
}

//程序说明

void GiveInstructions(void)
{
 printf("This program displays a calendar for a full\n");
 printf("year. The year must not be before 1900.\n");
}

//获取年份

int GetYearFromUser(void)
{
 int year;

 while (TRUE)
 {
  printf("Which year?");
  year=GetInteger();
  if (year>=1900) return (year);
  printf("The year must be at least 1900.\n");
 }
}

//打印日历函数

void PrintCalendar(int year)
{
 int month;

 for (month=1;month<=12;month++)
 {
  PrintCalendarMonth(month,year);
  printf("\n");
 }
}

//打印月份

void PrintCalendarMonth(int month,int year)
{
 int weekday,nDays,day;

 printf("    %s %d\n",MonthName(month),year);
 printf(" Su Mo Tu We Th Fr Sa\n");
 nDays=MonthDays(month,year);
 weekday=FirstDayOfMonth(month,year);
 IndentFirstLine(weekday);
 for (day=1;day<=nDays;day++)
 {
  printf(" -",day);
  if (weekday==Saturday)
  {
   printf("\n");
  }
  weekday=(weekday+1)%7;
 }
 if (weekday!=Sunday)
 {
  printf("\n");
 }
}

//显示第一行

void IndentFirstLine(int weekday)
{
 int i;

 for (i=0;i<weekday;i++)
 {
  printf("   ");
 }
}

//计算月份的天数

int MonthDays(int month,int year)
{
 switch (month)
 {
  case 2:
   if (IsLeapYear(year))
   {
    return (29);
   }
   return (28);
  case 4:
  case 6:
  case 9:
  case 11:
   return(30);
  default:
   return (31);
 
}

//计算月份中第一天是星期几

int FirstDayOfMonth(int month,int year)
{
 int weekday,i;

 weekday=Monday;
 for (i=1900;i<year;i++)
 {
  weekday=(weekday+365)%7;
  if(IsLeapYear(i))
   weekday=(weekday+1)%7;
 }
 for (i=1;i<month;i++)
 {
  weekday=(weekday+MonthDays(i,year))%7;
 }
 return (weekday);
}

//显示月份的名字

string MonthName(int month)
{
 switch(month)
 {
 case   1: return ("January");
 case   2: return ("February");
 case   3: return ("March");
 case   4: return ("April");
 case   5: return ("May");
 case   6: return ("June");
 case   7: return ("July");
 case   8: return ("August");
 case   9: return ("September");
 case  10: return ("October");
 case  11: return ("November");
 case  12: return ("December");
 default:  return ("Illegal month");
 }
}

//判断是否为闰年

bool IsLeapYear(int year)
{
 return (((year%4==0)&&(year0!=0))||(year@0==0));
}
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值