C語言打印年曆

摘要:使用C語言打印年曆

  最初看到這個是以爲比較有意思,記得讀書時候只寫過月曆,年曆要複雜一些,如今水平提升了,來從新寫一下吧。數組

  看了網上的一些代碼,大都比較繁瑣,本文采用全新的思路完成年曆打印。函數

總體思路:

  來看一下效果吧:spa

  

  看了一下網上的代碼,思路大都是一行一行打印,這樣涉及到月份,星期以及月首的空格打印都很是複雜,致使代碼量龐大,而且邏輯很是複雜,本文旨在使用全新的思路,使用較好理解的代碼,以及較少的代碼量完成年曆打印。code

  先講思路,咱們知道,每個月最多31天,打印出來5~6行(每行最多7個),傳統方法複雜的緣由在於只能逐行打印。本文使用一個21 X 24的二維數組(每月佔用7 X 6個空間),用來保存當月的日期,接下來上代碼。blog

代碼解釋:

  cal_first函數用來計算月首第一天是星期幾,方便肯定正確的打印位置。數學

int cal_first(int y, int m)
{
    int d = 1;
    if(m<=2) 
    {
        m += 12;
        y -= 1;
    }
    return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7 + 1;
}

  接下來是show_year函數,略微複雜。table

void show_year(int year)
{
    int i,j,k,t,n;                           // 用來輔助計數
    int table[24][21] = {0};                     // 年曆數組
    int month_day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; // 每個月上限天數
    if ((0 == year%4 || 0 == year%400) && 0 != year%100)    // 閏年檢查,若是是閏年,2月上限天數改成29
    {   
        month_day[2] = 29;
    }
    printf ("                                       ******************\n");
    printf ("                                              %d        \n", year);
    printf ("                                       ******************\n");
    for (i=0; i<12; i++)                        // 爲了使邏輯更加清晰,一次循環只完成一個月的日期填寫,i爲當前月份
    {
        n = cal_first(i+1);                     // n爲當前月份第一天的星期數,cal_first函數中的月數必須爲1~12,
        for (j=(i/3)*6; j<(i/3)*6+6; j++)             // 因此這裏傳參時+1,j用來根據月數控制每月在年曆數組中的第一維座標
        {                                // 座標(縱座標)的位置,一樣的,用來根據月數控制每月在年曆數組中
            for (k=(i%3)*7; k<(i%3)*7+7; k++)          // 第二維座標(橫座標)的位置
            {
                t = (j%6)*7 + k%7 - n + 2;            // t用來臨時記錄當前位置應該填入年曆數組的值,爲了簡化邏輯,這裏經過
                if (0 >= t)                     // 數學計算記錄每個位置應填入的值,(j%6)*7 + k%7計算出的值是本
                {                           // 月的第幾個位置,-n+2就會計算出當前格內正確的日期。這樣作會致使得出
                    continue;                    // 負數或0,或炒熟每個月天數上限,咱們用if + continue將其跳過,這樣
                }                           // 不正確的日期就依然是年曆數組初始化時的0
                if (t <= month_day[i])
                {
                    table[j][k] = t;
                }
                else
                {
                    continue;
                }
            }
        }
    }
    for (i=0; i<24; i++)                      // 至此,年曆數組已經所有填好,接下來是打印環節,相信已經比較好理解了
    {                                 //  每隔6行打印標頭,7列多打印幾個空格,遇到數組中爲0則一樣打印空格
        if (0 == i)
        {
            printf ("              Jan                             Feb                             Mar\n");
            printf ("  Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun\n");
        }
        if (6 == i)
        {
            printf ("              Apr                             May                             Jun\n");
            printf ("  Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun\n");
        }
        if (12 == i)
        {
            printf ("              Jul                             Agu                             Sep\n");
            printf ("  Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun\n");
        }
        if (18 == i)
        {
            printf ("              Oct                             Nov                             Dec\n");
            printf ("  Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun     Mon Tue Wen Thu Fir Sat Sun\n");
        }
        for (j=0; j<21; j++)
        {
            if (7 == j || 14 == j)
            {
                printf ("    ");
            }
            if (0 == table[i][j])
            {
                printf ("    ");
                continue;
            }
            printf ("%4d", table[i][j]);
        }
        printf ("\n");
    }
}

   代碼展現完畢,大約只有七、80行吧,歡迎留言討論。class

相關文章
相關標籤/搜索