最近在看《The C Programing Language》,進一步加深了自己對於指針賦值的理解,現在看來關於日期,天數這類的題目很是簡單,但是遙想當年大一的時候自己去參加計算機學院的編程大賽,五個問題只是求解出來一個,而沒解答出的問題中就包含關於日期天數的一個問題,今天爲了彌補一下以前的遺憾,就把這個程序再寫一寫吧。(話說程序還就需要多寫多練,本來以爲自己看書的時候想枚舉,多維數組,局部變量初始化等問題都是很簡單的,但是自己寫起來還是很費勁,說明自己寫的代碼還是少,需要加強訓練啊。)
#include <stdio.h>
#include <stdlib.h>
int monthday[2][12]=
{
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}
};
char *Month[] =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
int year_days(int year,int month,int day)
{
int leap,yeardays,i;
yeardays = 0;
leap = ((year%4==0 && year%100!=0) || (year%400==0));
for(i=0;i<month-1;i++)
yeardays += monthday[leap][i];
yeardays = yeardays+day;
return yeardays;
}
void month_day(int year,int yeardays,int* pmonth,int* pday)
{
int leap,i;
leap = ((year%4==0 && year%100!=0) || (year%400==0));
for(i=0;yeardays>monthday[leap][i];i++)
yeardays -= monthday[leap][i];
*pmonth = i;
*pday = yeardays;
}
int main()
{
int year = 1997;
int month = 3;
int day = 1;
int *pmonth;
int *pday;
int yeardays = year_days(year,month,day);
pmonth = (int*)malloc(sizeof(int));
pday = (int*)malloc(sizeof(int));
month_day(year,yeardays,pmonth,pday);
printf("The yeardays is %d\n",yeardays);
printf("The Month is %s, The Date is %d \n",Month[*pmonth],*pday);
return 0;
}
對於程序的完美運行需要進行用戶輸入的合法性判斷,下面是另外一個版本:
#include <stdio.h>
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};
/* day_of_year: set day of year from month & day */
int day_of_year(int year, int month, int day)
{
int i, leap;
if (year < 1752 || month < 1 || month > 12 || day < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if (day > daytab[leap][month])
return -1;
for (i = 1; i < month; i++)
day += daytab[leap][i];
return day;
}
/* month_day: set month, day from day of year */
int month_day(int year, int yearday, int *pmonth, int *pday)
{
int i, leap;
if (year < 1752 || yearday < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if ((leap && yearday > 366) || (!leap && yearday > 365))
return -1;
for (i = 1; yearday > daytab[leap][i]; i++)
yearday -= daytab[leap][i];
*pmonth = i;
*pday = yearday;
return 0;
}
/* main: test day_of_year and month_day */
int main(void)
{
int year, month, day, yearday;
for (year = 1970; year <= 2000; ++year) {
for (yearday = 1; yearday < 366; ++yearday) {
if (month_day(year, yearday, &month, &day) == -1) {
printf("month_day failed: %d %d\n",
year, yearday);
} else if (day_of_year(year, month, day) == yearday) {
printf("bad result: %d %d\n", year, yearday);
printf("month = %d, day = %d\n", month, day);
}
}
}
return 0;
}
下面是根據年月日求解當天星期幾的代碼
#include <stdio.h>
char *name[] = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" };
int main()
{
int d, m, y, a;
printf("Day: ");
scanf("%d",&d);
printf("Month: ");
scanf("%d",&m);
printf("Year: ");
scanf("%d",&y);
// 1213,14
if (m == 1 || m == 2)
{
m += 12;
y--;
}
// 175293
if ((y < 1752) || (y == 1752 && m < 9) || (y == 1752 && m == 9 && d < 3))
a = (d + 2*m + 3*(m+1)/5 + y + y/4 +5) % 7;
else
a = (d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400)%7;
printf("it's a %s\n", name[a]);
return 0;
}
根據代碼可以發現1752年9月3日是一個轉折點。說明那天發生了什麼大事,
現行的公曆是格利戈裏曆法,這個曆法的是1582年教皇格利戈里根據愷撒大帝引進的算法改進的。它採用的是閏年制也就是現行的制度,不過有一個需要注意的地方就是,這個曆法並不是連續的,中間缺少了11天。1752年9月2日之後的那一天並不是1752年9月3日,而是1752年9月14日。也就是說,從1752年9月3日到1752年9月13日的11天並不存在。抹掉這11天是由英國議會做出的決定。所以要計算某年每個月的天數的,除了要考慮是否是閏年以外,還要考慮1752年的9月。