首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言實作:根據基準日期計算任意日期的星期幾

     編輯:關於C

題目背景與需求

給定基準日期為 2007 年 10 月 17 日(星期六),輸入任意合法日期(年、月、日),程式需輸出該日期對應的星期幾;若輸入日期不合法,則輸出 "illegal"。輸入包含多組測試資料,每組佔一行,直到 EOF 結束。

核心邏輯解析

1. 閏年判斷

採用標準規則:能被 4 整除但不能被 100 整除,或能被 400 整除的年份為閏年。

int isLeap(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

2. 日期合法性檢查

  • 年份範圍:0 < year < 10000
  • 月份範圍:1 ~ 12
  • 日期範圍:依月份與是否閏年動態判斷(如 2 月平年 28 天、閏年 29 天)

3. 計算與基準日(公元元年 1 月 1 日)的天數差

累加完整年份的天數、當年已過月份的天數,再加上當月日期,總和即為距離基準日的總天數。

for (k = 1; k < year; k++)
    days += isLeap(k) ? 366 : 365;

for (j = 0; j < month; j++)
    days += isLeap(year) ? year2[j] : year1[j];

days += day;

4. 取模 7 對應星期

由於 2007/10/17 是星期六,若以公元元年 1 月 1 日為起點,需根據實際對應關係調整陣列順序。程式中直接以 days % 7 作為索引,對應 date[7] = {"星期日","星期一",...,"星期六"}。

常見錯誤與注意事項

  • C89 標準限制:舊標準下 for 迴圈內不可宣告變數(如 for(int i=0;...)),需在函數開頭宣告所有變數。
  • 陣列索引邊界:year1、year2 陣列大小為 13,索引 1~12 對應月份,索引 0 置 0 以便迴圈累加。
  • 輸入結束判斷:使用 scanf(...) != EOF 讀取多組測資。

完整程式碼參考

#include 

char date[7][7] = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

int isLeap(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

int main() {
    int year, month, day;
    int year1[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    int year2[13] = {0,31,29,31,30,31,30,31,31,30,31,30,31};
    int days, k, j;
    char *getDate;

    while (scanf("%d %d %d", &year, &month, &day) != EOF) {
        // 合法性檢查
        if (year <= 0 || year >= 10000 || month <= 0 || month >= 13 || day <= 0 || day >= 32) {
            printf("illegal\n");
            continue;
        }

        // 針對 2 月與閏年做額外檢查
        if (month == 2) {
            int maxDay = isLeap(year) ? year2[2] : year1[2];
            if (day > maxDay) {
                printf("illegal\n");
                continue;
            }
        } else if (day > year1[month]) { // 平年月份天數同閏年(除 2 月外)
            printf("illegal\n");
            continue;
        }

        days = 0;
        for (k = 1; k < year; k++)
            days += isLeap(k) ? 366 : 365;

        for (j = 0; j < month; j++)
            days += isLeap(year) ? year2[j] : year1[j];

        days += day;
        getDate = date[days % 7];
        printf("%s\n", getDate);
    }
    return 0;
}

測試與驗證

文章附帶測試截圖顯示程式正確輸出星期資訊,並提醒在 C89 環境下編譯時需將迴圈變數移至函數頂部宣告,否則會報錯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved