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

C語言萬年曆顯示錯誤?核心邏輯錯誤定位與修正方案

     編輯:程式設計綜合問答

問題現象:月曆日期排版錯亂

開發者編寫的萬年曆程式,輸入年份後顯示 12 個月份,但日期列對齊錯誤、換行混亂,導致日曆無法正常閱讀。

原始碼關鍵片段(有錯誤的雙重迴圈)

for (int w = 1; w <= 5; w++) { // 最多 5 週
    for (int j = 0; j < 3; j++) { // 每行 3 個月
        int m;
        for (m = 1; m <= 7; m++, a[j]++) {
            if (a[j] > b[j]) break;
            cout << setw(2) << setfill(' ') << a[j] << " ";
            k++; a[j] = k; // 邏輯混淆
        }
        cout << " ";
    }
    cout << endl;
}

根因分析:迴圈變數與日期計數器耦合導致邏輯失控

  1. a[j] 同時作為「當前日期」與「迴圈計數器」,導致 m 與 a[j] 同步遞增,日期跳躍。
  2. break 跳出內層迴圈後,外層 w 繼續,但 a[j] 已超過該月天數 b[j],後續迴圈只輸出空白。
  3. 缺少「當月日期已印完,後續週只印空白」的明確狀態控制。

修正方案:分離「日期計數」與「格子迴圈」,引入狀態標記

for (int w = 1; w <= 5; w++) {
    for (int j = 0; j < 3; j++) {
        int m;
        for (m = 1; m <= 7; m++, a[j]++) {
            // 關鍵修正:若該月日期已印完,直接印空格佔位
            if (a[j] > b[j]) 
                cout << "   "; // 3 字元寬度對齊
            else 
                cout << setw(2) << setfill(' ') << a[j] << " ";
        }
        cout << " "; // 月份間距
    }
    cout << endl;
}

關鍵改動說明

  • 移除 break:改用 if-else 統一處理「印日期」與「印空白」,確保內層迴圈始終跑滿 7 次(一週 7 天),保證欄位對齊。
  • 統一輸出寬度:空白也用 3 字元(" "),與 setw(2) << " " << 的視覺寬度一致。
  • 保持 a[j] 遞增:即使印空白也繼續遞增,簡化邏輯;實際上 a[j] > b[j] 後不再使用其值,無副作用。

完善建議:前置條件檢查與邊界處理

  1. 在進入週迴圈前,先判斷該月是否已全部列印完(a[j] > b[j]),若三個月皆結束可提前 break 外層迴圈,提升效能。
  2. 利用 std::vector<int> 替代固定陣列 a[10]、b[10],增強擴展性。
  3. 將「某月第一天是星期幾」封裝為 getFirstWeekday(year, month) 函式,提高可讀性。

總結: 萬年曆的核心難點在於「二維網格(週×星期)映射一維日期序列」的邊界控制。將「印數字」與「印佔位符」統一在同一個迴圈分支中,是避免排版錯亂的關鍵模式。

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