1. 寫了個萬年曆的功能練練手。尚未寫交互的代碼,只是把方法寫完了。先給出頭部和方法簽名算法
#include<stdio.h> #define DAYS_PER_WEEK 7 #define MONTHS 12 #define DATE_HEADER " Sun Mon Tues Wed Thur Fri Sat"
int get_days(int, int, int); //返回從公元元年算起,某年某月某日是第幾天, 用這個數字算星期幾 int days_of_year(int, int, int); //返回某年某月某日是當前年份第幾天 int days_of_month(int, int); //返還某年某月有幾天 int day_of_week(int, int, int); //返回某年某月某日是星期幾,星期天返回0 _Bool is_leap_year(int); //返回當前年份是否爲閏年 void print_date_of_month(int, int); // 打印某年某月的日曆
2.從最簡單的兩個方法開始測試
判斷閏年: 能整除400的年份 或者 能整除4,可是不能整除100的年份爲閏年spa
//判斷是否是閏年 _Bool is_leap_year(int year) { return (year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0); }
求某年莫個月份有多少天, 主要是閏年和平年在2月份的區別,閏年2月份有29天,平年2月份28天code
//返回這個月一共有多少天 int days_of_month(int year, int month) { //存儲平年每個月的天數 const int month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(2 == month && is_leap_year(year)) return 29; // 若是是閏年2月,返回29天 else return month_days[month-1]; //正常返回 }
從公元1年1月一日開始算,求某年某月某日是第幾天。blog
算法:1.先算全年的部分:好比2018年,完整已通過了的年份有2017個,按平年算有 2017 * 365 天,可是其中閏年是366天,每一個閏年少算了一天。1至2017有幾個閏年呢, 首先從閏年的定義:能整除400的年份 或者 能整除4,可是不能整除100的年份爲閏年get
閏年的數量 = 整除4的數量 - 整除100的數量 + 整除400的數量 input
因此最後的結果是 2017 * 365 + 閏年的數量 + 2018年1月1日到當前日期的天數it
//返回這一天從公元元年算起是第幾天 int get_days(int year, int month, int day) { int days = days_of_year(year, month, day); int temp = year-1; return temp * 365 + temp / 4 - temp / 100 + temp / 400 + days; }
從當前年份1月1日算起,某年某月某日是第幾天. io
思路很簡單就是累加完整月的天數 + 當月日期class
//返回這一天在當年是第幾天 int days_of_year(int year, int month, int day) { int i; int days = 0; for(i = 1; i < month; i++) { days += days_of_month(year, i); } return days + day; }
計算某年某月某日是星際幾
由於公元元年1月1日是星期1,因此先算出從公元元年算起,當前日期是第幾天,而後對7求模,星期天的時候返回 0
int day_of_week(int year, int month, int day) { return get_days(year, month, day) % DAYS_PER_WEEK; }
打印某年某個月的日曆
//思路就是先肯定當月1號是周幾,先打印1號,而後剩下的根據1號來推
//輸出某年某個月的日曆 void print_date_of_month(int year, int month) { //打印月份,爲了讓月份顯示居中, 打印一些空格(根據打印星期的那行大概估算一下) printf(" "); switch(month) { case 1: printf("January\n"); break; case 2: printf("February\n"); break; case 3: printf("March\n"); break; case 4: printf("April\n"); break; case 5: printf("May\n"); break; case 6: printf("June\n"); break; case 7: printf("July\n"); break; case 8: printf("August\n"); break; case 9: printf("September\n"); break; case 10: printf("October\n"); break; case 11: printf("November\n"); break; case 12: printf("December\n"); break; default: printf("Bad input of month, please enter a right month.\n"); return; } //先把星期打印出來 printf("%s\n", DATE_HEADER); //先求出這個月第一天星期幾 int day_of_week = get_days(year, month, 1) % DAYS_PER_WEEK; //由於星期天是在第一個位置,因此對星期求模(求餘),好比星期天,實際上是第一個位置,因此它應該是 7 % 7 = 0; int first = day_of_week % DAYS_PER_WEEK; //求出這個月一共有幾天 int days = days_of_month(year, month); int i, j; //先打印第一天的位置 for(i = 0; i < first; i++) { printf(" "); } printf("%6d", 1); //若是今天是星期六,換行 if(first == 6) printf("\n"); //打印剩下的日期 for(i = 1; i < days; i++) { printf("%6d", i + 1); //若是是星期六或者是最後一天,換行 if((first + i) % 7 == 6 || i + 1 == days) printf("\n"); } }
.最後附上完整代碼
#include<stdio.h> #define DAYS_PER_WEEK 7 #define MONTHS 12 #define DATE_HEADER " Sun Mon Tues Wed Thur Fri Sat" int get_days(int, int, int); //返回從公元元年算起,某年某月某日是第幾天, 用這個數字算星期幾 int days_of_year(int, int, int); //返回某年某月某日是當前年份第幾天 int days_of_month(int, int); //返還某年某月有幾天 int day_of_week(int, int, int); //返回某年某月某日是星期幾,星期天返回0 _Bool is_leap_year(int); //返回當前年份是否爲閏年 void print_date_of_month(int, int); // 打印某年某月的日曆 int main() { int days = get_days(2018, 5, 9) % DAYS_PER_WEEK; printf("%d\n", day_of_week(2018, 5, 9)); print_date_of_month(2018, 8); return 0; } //返回這一天從公元元年算起是第幾天 int get_days(int year, int month, int day) { int days = days_of_year(year, month, day); int temp = year-1; return temp * 365 + temp / 4 - temp / 100 + temp / 400 + days; } //返回這一天在當年是第幾天 int days_of_year(int year, int month, int day) { int i; int days = 0; for(i = 1; i < month; i++) { days += days_of_month(year, i); } return days + day; } //返回這個月一共有多少天 int days_of_month(int year, int month) { //存儲平年每個月的天數 const int month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(2 == month && is_leap_year(year)) return 29; // 若是是閏年2月,返回29天 else return month_days[month-1]; //正常返回 } //判斷是否是閏年 _Bool is_leap_year(int year) { return (year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0); } int day_of_week(int year, int month, int day) { return get_days(year, month, day) % DAYS_PER_WEEK; } //輸出某年某個月的日曆 void print_date_of_month(int year, int month) { //打印月份,爲了讓月份顯示居中, 打印一些空格(根據打印星期的那行大概估算一下) printf(" "); switch(month) { case 1: printf("January\n"); break; case 2: printf("February\n"); break; case 3: printf("March\n"); break; case 4: printf("April\n"); break; case 5: printf("May\n"); break; case 6: printf("June\n"); break; case 7: printf("July\n"); break; case 8: printf("August\n"); break; case 9: printf("September\n"); break; case 10: printf("October\n"); break; case 11: printf("November\n"); break; case 12: printf("December\n"); break; default: printf("Bad input of month, please enter a right month.\n"); return; } //先把星期打印出來 printf("%s\n", DATE_HEADER); //先求出這個月第一天星期幾 int day_of_week = get_days(year, month, 1) % DAYS_PER_WEEK; //由於星期天是在第一個位置,因此對星期求模(求餘),好比星期天,實際上是第一個位置,因此它應該是 7 % 7 = 0; int first = day_of_week % DAYS_PER_WEEK; //求出這個月一共有幾天 int days = days_of_month(year, month); int i, j; //先打印第一天的位置 for(i = 0; i < first; i++) { printf(" "); } printf("%6d", 1); //若是今天是星期六,換行 if(first == 6) printf("\n"); //打印剩下的日期 for(i = 1; i < days; i++) { printf("%6d", i + 1); //若是是星期六或者是最後一天,換行 if((first + i) % 7 == 6 || i + 1 == days) printf("\n"); } }
跑起來測試結果, 打印的日曆是2018年8月的