上一篇中打印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語言代碼訓練營(第七天)