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

C語言打印年曆:完整算法與代碼實現(含閏年、星期計算)

     編輯:C 語言問答

核心算法步驟

  1. 輸入年份
  2. 判斷閏年:(y%4==0 && y%100!=0) || (y%400==0)
  3. 計算該年 1 月 1 日星期幾(蔡勒公式/基姆拉爾森公式)
  4. 按月迭代打印:對齊首行空格 → 逐日打印 → 換行邏輯

完整可運行代碼


#include 

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

// 蔡勒公式:返回 0=周日 ... 6=周六
int weekday_1_1(int y) {
    // 以 1900-01-01 (周一) 為基準
    // 簡化版:1900 年 1 月 1 日是周一 (1)
    int days = 0;
    for (int i = 1900; i < y; i++)
        days += is_leap(i) ? 366 : 365;
    return (days + 1) % 7;  // 0=Sun
}

void print_month(int year, int month, int *weekday) {
    static const int mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int days = mdays[month - 1];
    if (month == 2 && is_leap(year)) days = 29;

    static const char *mname[12] = {
        "January","February","March","April","May","June",
        "July","August","September","October","November","December"
    };

    printf("\n      %s %d\n", mname[month-1], year);
    printf(" Sun Mon Tue Wed Thu Fri Sat\n");

    // 打印首行前導空格
    for (int i = 0; i < *weekday; i++) printf("    ");

    for (int d = 1; d <= days; d++) {
        printf("%4d", d);
        if (++(*weekday) == 7) {
            printf("\n");
            *weekday = 0;
        }
    }
    printf("\n");
}

int main() {
    int year;
    printf("輸入年份 (如 2024): ");
    scanf("%d", &year);

    int wd = weekday_1_1(year);
    for (int m = 1; m <= 12; m++)
        print_month(year, m, &wd);

    return 0;
}

關鍵點解析

優化版:單行蔡勒公式


// 返回 0=周日 ... 6=周六,適用 1582 年後
int zeller(int y, int m, int d) {
    if (m < 3) m += 12, y--;
    return (d + 13*(m+1)/5 + y + y/4 - y/100 + y/400) % 7;
}
// 1月1日星期:zeller(year, 1, 1)

常見錯誤避坑

  1. 數組 day[12] 未隨閏年更新 2 月天數
  2. week 變量未在月份間正確傳遞(需指針或全局)
  3. 打印循環中 week 遞增與換行判斷順序錯誤
  4. 輸入年份超出 int 範圍(不實際)

擴展功能建議

  • 高亮今天(ANSI 色碼)
  • 顯示農曆/節氣(查表/算法)
  • 輸出 HTML/Markdown/圖片
  • 命令行參數 ./cal 2024 5 只顯示指定月
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題解決方案
閏年判斷標準格雷戈里曆規則,2 月 28/29 天動態調整
1月1日星期蔡勒公式/累積天數法,注意基準日選擇
月曆對齊weekday 變量跨月傳遞,自動銜接上月結尾
輸出格式%4d 固定寬度,保證列對齊
十月末多一行原代碼 if(i==10) 殘留邏輯導致,刪除即可