上一篇中打印2015年日歷的程序不知道大家是否寫出了,今天我們來用標(biāo)準(zhǔn)程序設(shè)計的思想來解決這個問題。
1. 功能分析
在程序設(shè)計過程中,我們需要把最基本的功能分析出來蔼夜,之后封裝成功能函數(shù)。這樣压昼,在最后主程序中只需要通過各種函數(shù)調(diào)用像搭積木一樣把這些功能組合起來就OK了求冷。下面我們具體看看這道題。
1.1 月份打印
打印月份是個比較麻煩的工作巢音,我們需要寫一個函數(shù)遵倦,輸入int型的月份,在屏幕中打印出相應(yīng)的月份名稱官撼。
首先梧躺,我們編程實現(xiàn)打印一年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;
}
執(zhí)行結(jié)果如下:
這個程序中傲绣,我們通過一個二維數(shù)組保存每個月的字母名稱掠哥,之后通過數(shù)組下標(biāo)完成相應(yīng)的月份打印。現(xiàn)在我們把核心功能進(jìn)行函數(shù)封裝秃诵。代碼如下:
char g_month[12][10] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
// 通過月份數(shù)字打印月份名稱
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函數(shù)和全局變量g_month就是我們封裝的打印月份的功能续搀。
1.2 判斷閏年
知道了平年還是閏年才能知道2月份究竟是幾天。因此這個函數(shù)必不可少菠净。
// 判斷閏年禁舷,是閏年返回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 判斷每個月的天數(shù)
這里需要一個通過年份和月份判斷天數(shù)的函數(shù)毅往。代碼如下:
int g_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 返回輸入的年份中輸入的月份天數(shù)
int GetDays(int year, int month)
{
if (month == 2 && IsLeapYear(year))
{
return g_days[month - 1] + 1;
}
else
{
return g_days[month - 1];
}
}
又是一個全局變量和一個函數(shù)的組合牵咙,這種形式其實是數(shù)據(jù)結(jié)構(gòu)的思想,通過一個或一些函數(shù)來管理一段空間的操作攀唯。
2. 功能函數(shù)組合
正題流程如下:
- 判斷當(dāng)年1月1日是周幾
- 循環(huán)12個月洁桌,每個循環(huán)單元中執(zhí)行下面的工作:
- 打印月份名
- 打印星期表頭
- 通過打印空格找到本月1日的具體位置
- 計算出當(dāng)月有多少天
- 依次打印出每一天,每7個數(shù)字一次折行
代碼實現(xiàn)中侯嘀,盡量使用前面封裝好的函數(shù)另凌。代碼如下:
#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};
// 通過月份數(shù)字打印月份名稱
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;
}
// 返回輸入的年份中輸入的月份天數(shù)
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;
// 計算當(dāng)年的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(" "); // 每月一號對齊它的星期數(shù)
// 這個月的每一天和星期對齊輸出
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;
}
執(zhí)行結(jié)果如下:
今天的講解主要以代碼進(jìn)行展示吠谢,如果有問題歡迎探討土童。
3. 課后練習(xí)題
今天這個題目可以繼續(xù)追加功能,請自己完成輸入任意年份打印當(dāng)年的日歷工坊。同時娜扇,把12個月的日歷打印成6行2列。請仔細(xì)思考一下栅组。
我是天花板,讓我們一起在軟件開發(fā)中自我迭代枢析。
如有任何問題玉掸,歡迎與我聯(lián)系。