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的年份為閏年
//判斷是不是閏年
_Bool is_leap_year(int year)
{
return (year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0);
}
求某年莫個月份有多少天, 主要是閏年和平年在2月份的差別,閏年2月份有29天,平年2月份28天
//傳回這個月一共有多少天
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月一日開始算,求某年某月某日是第幾天。
算法:1.先算整年的部分:比如2018年,完整已經過了的年份有2017個,按平年算有 2017 * 365 天,但是其中閏年是366天,每個閏年少算了一天。1至2017有幾個閏年呢, 首先從閏年的定義:能整除400的年份 或者 能整除4,但是不能整除100的年份為閏年
閏年的數量 = 整除4的數量 - 整除100的數量 + 整除400的數量
是以最後的結果是 2017 * 365 + 閏年的數量 + 2018年1月1日到目前日期的天數
//傳回這一天從公元元年算起是第幾天
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日算起,某年某月某日是第幾天.
思路很簡單就是累加完整月的天數 + 當月日期
//傳回這一天在當年是第幾天
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月的

歡迎通路我的個人部落格站點:
https://yeyeck.com