算法邏輯
- 判斷閏年:
(year%4==0 && year%100!=0) || (year%400==0)。
- 預置平年/閏年每月天數表(含第 0 月佔位)。
- 累加前
month-1 月天數,再加 day。
代碼實現
#include <stdio.h>
#include <stdlib.h>
#define isleap(y) (((y)%4==0 && (y)%100!=0) || (y)%400==0)
static int month_days[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} // 閏年
};
int day_of_year(int year, int month, int day) {
int leap = isleap(year);
int sum = day;
for (int m = 1; m < month; m++) sum += month_days[leap][m];
return sum;
}
int main() {
int y, m, d;
printf("請輸入日期 (yyyy-mm-dd):");
scanf("%d-%d-%d", &y, &m, &d);
printf("第 %d 天\n", day_of_year(y, m, d));
return 0;
}
運行示例
輸入: 2016-02-23
輸出: 第 54 天
關鍵點
- 宏
isleap 避免函數調用開銷,編譯期展開。
- 二維數組
month_days[2][13] 以閏年標誌為索引,查表 O(1)。
- 循環累加月份,簡單清晰;也可預計算前綴和數組進一步優化至 O(1) 無循環。
- 輸入格式解析用
scanf("%d-%d-%d") 直接匹配分隔符。
擴展
- 增加合法性檢查(月 1-12、日 1-當月天數)。
- 支持儒略日、ISO 週日期等其他曆法轉換。
- 嵌入式環境可用查表法完全消除分支與循環。