21天C語言代碼訓練營(第六天)

上一篇中打印2015年日歷的程序不知道大家是否寫出了,今天我們來用標準程序設計的思想來解決這個問題。

1. 功能分析

在程序設計過程中,我們需要把最基本的功能分析出來,之后封裝成功能函數。這樣,在最后主程序中只需要通過各種函數調用像搭積木一樣把這些功能組合起來就OK了。下面我們具體看看這道題。

1.1 月份打印

打印月份是個比較麻煩的工作,我們需要寫一個函數,輸入int型的月份,在屏幕中打印出相應的月份名稱。

首先,我們編程實現打印一年12個月份的程序。程序如下:

int main()
{
    int i;
    char month[12][10]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

    for (i = 0; i < 12; i++)
    {
        printf("%s\n", month[i]);
    }

    return 0;
}

執行結果如下:

執行結果

這個程序中,我們通過一個二維數組保存每個月的字母名稱,之后通過數組下標完成相應的月份打印。現在我們把核心功能進行函數封裝。代碼如下:

char g_month[12][10] = {"January", "February", "March", "April", "May", "June",
                    "July", "August", "September", "October", "November", "December"};

// 通過月份數字打印月份名稱
void PrintMonth(int month)
{
    printf("%s", g_month[month - 1]);
}

int main()
{
   int i;
   for (i = 0; i < 12; i++)
   {
       PrintMonth(i + 1);
       printf("\n");
   }

   return 0;
}

這段代碼中的PrintMonth函數和全局變量g_month就是我們封裝的打印月份的功能。

1.2 判斷閏年

知道了平年還是閏年才能知道2月份究竟是幾天。因此這個函數必不可少。

// 判斷閏年,是閏年返回1,是平年返回0
int IsLeapYear(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        return 1;
    else
        return 0;
}

1.3 判斷一年的第一天是周幾

代碼如下:

// 返回輸入年份的1月1日是周幾
int GetWeek(int year)
{
    return (35 + year + year / 4 - year / 100 + year / 400) % 7;
}

1.4 判斷每個月的天數

這里需要一個通過年份和月份判斷天數的函數。代碼如下:

int g_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// 返回輸入的年份中輸入的月份天數
int GetDays(int year, int month)
{
    if (month == 2 && IsLeapYear(year))
    {
        return g_days[month - 1] + 1;
    }
    else
    {
        return g_days[month - 1];
    }
}

又是一個全局變量和一個函數的組合,這種形式其實是數據結構的思想,通過一個或一些函數來管理一段空間的操作。

2. 功能函數組合

正題流程如下:

  • 判斷當年1月1日是周幾
  • 循環12個月,每個循環單元中執行下面的工作:
    • 打印月份名
    • 打印星期表頭
    • 通過打印空格找到本月1日的具體位置
    • 計算出當月有多少天
    • 依次打印出每一天,每7個數字一次折行

代碼實現中,盡量使用前面封裝好的函數。代碼如下:

#include <stdio.h>

char g_month[12][10] = {"January", "February", "March", "April", "May", "June",
                    "July", "August", "September", "October", "November", "December"};

int g_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// 通過月份數字打印月份名稱
void PrintMonth(int month)
{
    printf("%s", g_month[month - 1]);
}

// 判斷閏年,是閏年返回1,是平年返回0
int IsLeapYear(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        return 1;
    else
        return 0;
}

// 返回輸入年份的1月1日是周幾
int GetWeek(int year)
{
    return (35 + year + year / 4 - year / 100 + year / 400) % 7;
}

// 返回輸入的年份中輸入的月份天數
int GetDays(int year, int month)
{
    if (month == 2 && IsLeapYear(year))
    {
        return g_days[month - 1] + 1;
    }
    else
    {
        return g_days[month - 1];
    }
}

int main()
{
    int i, j, k;
    int week;
    int days;
    int year = 2015;

    // 計算當年的1月1日是周幾的公式
    week = GetWeek(year);

   for(i = 0; i < 12; i++)
   {
       printf("\n");

       PrintMonth(i + 1);

       printf("\n");

       printf("---------------------------\n");
       printf("Sun Mon Tue Wed Thu Fri Sat\n");

       for(k = 0; k < week; k++)
           printf("    "); // 每月一號對齊它的星期數

       // 這個月的每一天和星期對齊輸出
       days = GetDays(year, i + 1);
       for(j = 1; j <= days; j++)
       {
            printf("%3d ", j);
            if(++week >= 7)
            {
                printf("\n");
                week = week % 7;
            }
        }
        printf("\n");
    }
    return 0;
}

執行結果如下:

Part-1.png
Part-2.png
Part-3.png

今天的講解主要以代碼進行展示,如果有問題歡迎探討。

3. 課后練習題

今天這個題目可以繼續追加功能,請自己完成輸入任意年份打印當年的日歷。同時,把12個月的日歷打印成6行2列。請仔細思考一下。

我是天花板,讓我們一起在軟件開發中自我迭代。
如有任何問題,歡迎與我聯系。


上一篇:21天C語言代碼訓練營(第五天)
下一篇:21天C語言代碼訓練營(第七天)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,117評論 25 708
  • 繼續我們之前的項目,上一篇中我們完成了自己的String類型設計,封裝了相關的功能。有朋友留言中提到C語言中有相應...
    天花板閱讀 4,055評論 8 52
  • 上一篇中我們用項目思維把我們的程序做了大的調整,收到的大部分反饋郵件都說基本能看懂。今天我們來實現最后一部分功能。...
    天花板閱讀 3,922評論 17 49
  • 順著你的方向是斟滿酒的杯盞是要離岸的船只是即將倒塌的鼓樓 于一千零一夜你檠著通明的月亮來尋這滿山的坡石來尋這喧囂的...
    買金礦閱讀 509評論 8 27
  • 菠蘿大叔尋找小菠蘿的故事在村子里都傳開了,人們看著一個愛子情深的父親守望的眼神,每個人都在心里默念著,如果看到了大...
    汪八萬閱讀 1,189評論 0 1