首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言計算同年生日天數差:Switch 缺少 break 導致 Case 貫穿錯誤

     編輯:程式設計綜合問答

題目:輸入同年的兩個生日(月/日),輸出兩日期相差天數。原代碼邏輯正確,但 switch 缺少 break 導致 Case 貫穿,造成累加天數錯誤。以下詳細解析並給出修正版。

錯誤根因:Switch 隱式貫穿

switch(i) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        s += 31;
    case 4: case 6: case 9: case 11:   // ❌ 無 break,31天月份會繼續執行這裡再加 30
        s += 30;
    case 2:                            // ❌ 繼續執行閏年判斷
        if (leap) s += 29; else s += 28;
}

結果:1 月會被加上 31 + 30 + 28/29 = 89/90 天,完全錯誤。

修正版完整代碼

#include 
#include 

// 計算該年 1 月 1 日至指定月日 的天數(1-based)
int dayOfYear(int year, int month, int day) {
    static const int monthDays[12] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    int sum = 0;
    for (int m = 1; m < month; ++m) {
        if (m == 2) {
            // 閏年判斷:能被400整除,或能被4整除但不能被100整除
            int leap = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
            sum += leap ? 29 : 28;
        } else {
            sum += monthDays[m - 1];
        }
    }
    return sum + day;
}

int main() {
    int year, m1, d1, m2, d2;
    if (scanf("%d %d %d", &year, &m1, &d1) != 3) return 1;
    if (scanf("%d %d", &m2, &d2) != 2) return 1;

    int n1 = dayOfYear(year, m1, d1);
    int n2 = dayOfYear(year, m2, d2);
    int diff = abs(n1 - n2);
    printf("%d\n", diff);
    return 0;
}

關鍵修正點對比

原代碼問題修正做法
switch 缺 break 導致貫穿改用陣列 monthDays + 迴圈,完全避開 switch
閏年判斷條件寫在 case 內,易漏 break獨立函式 isLeap(year) 判斷,邏輯清晰
輸入格式假設固定,無錯誤處理檢查 scanf 返回值,增強健壯性
變數命名單一字母,可讀性差語義化命名:dayOfYear, monthDays, leap

測試驗證

輸入:
1997 2 27
3 10
輸出:
11   ← 正確(3/10 是第 69 天,2/27 是第 58 天,差 11 天)

輸入:
2000 1 1
12 31
輸出:
365  ← 閏年 366 天,首尾相差 365 天

延伸:若允許跨年計算

改用標準庫 <time.h> 的 struct tm + mktime 轉換為 time_t 相減,自動處理閏年、跨年、時區:

time_t toTimeT(int y, int m, int d) {
    struct tm t = {0};
    t.tm_year = y - 1900;
    t.tm_mon = m - 1;
    t.tm_mday = d;
    return mktime(&t);
}
double diffDays = difftime(toTimeT(y2,m2,d2), toTimeT(y1,m1,d1)) / 86400.0;

核心教訓:C 語言 switch 須加 break,否則會貫穿執行後續 case;改用資料驅動(陣列/表格)往往比分支語句更簡潔、不易出錯。

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