上一篇中我們用項目思維把我們的程序做了大的調整削咆,收到的大部分反饋郵件都說基本能看懂口芍。今天我們來實現(xiàn)最后一部分功能。
今天的程序修改都是在上一篇的基礎上進行菩收,請先打開之前的項目梨睁。
1. 功能函數(shù)封裝
首先要說的是main.c這個文件。在這個文件的前半部分是一些功能函數(shù)娜饵,從邏輯上講坡贺,這些函數(shù)和主程序的關系并不是非常密切。如果是一個很大的工程箱舞,就會出現(xiàn)在很多其他文件中多次調用這些函數(shù)的情況拴念。試想,如果我們在Month.c和String.c中也需要調用GetMonthStr這個函數(shù)褐缠,是不是訪問不到呢政鼠?請大家先自己試驗一下。
為了解決這種問題队魏,我們把這幾個函數(shù)獨立出來成為一組新的文件公般。
-
Function.h
#ifndef __FUNCTION_H__ #define __FUNCTION_H__ char* GetMonthStr(int month); int IsLeapYear(int year); int GetWeek(int year); int GetDays(int year, int month); #endif
-
Function.c
#include "Function.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ù)字打印月份名稱 char* GetMonthStr(int month) { return 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]; } }
此時的main.c文件中只有一個全局變量g_Month[12]和一個main函數(shù)了官帘。當然,別忘了在前面添加對Function.h的引用昧谊。
#include "Function.h"
2. 并排打印兩個月份
在Month.c中刽虹,我們通過PrintMonth這個函數(shù)打印每個月的日歷。如果我們需要一次并排打印兩個月份呢诬,那么需要在Month.c中添加一個新的函數(shù)涌哲。代碼如下:
// 并排打印兩個月的日歷
void PrintTwoMonth(Month* pMonthLeft, Month* pMonthRight)
{
int i;
printf("%27s\t", GetMonthName(pMonthLeft));
printf("%27s\n", GetMonthName(pMonthRight));
printf("----------------------------\t----------------------------\n");
printf("Sun Mon Tue Wed Thu Fri Sat\tSun Mon Tue Wed Thu Fri Sat\n");
for (i = 0; i < 6; i++)
{
printf("%27s\t", pMonthLeft->_arrayDays[i].buf);
printf("%27s\n", pMonthRight->_arrayDays[i].buf);
}
}
這個函數(shù)非常簡單,每次調用時傳入兩個月份的指針尚镰,之后每行前半部分打印左邊一個月的信息阀圾,后半部分打印右邊一個月的信息。
不要忘了在Month.h中添加這個函數(shù)的生命狗唉,否則main函數(shù)中無法調用初烘。
接下來,在main函數(shù)中,我們注釋掉之前的函數(shù)調用肾筐,加上PrintTwoMonth的調用即可哆料。修改部分如下:
// 打印12個月的日歷
for (i = 0; i < 12; i++)
{
//PrintMonth(&g_Month[i]);
PrintTwoMonth(&g_Month[i++], &g_Month[i]);
printf("\n");
}
讓我們來看看運行結果:
這時候大家就看到我們上一篇所做工作的好處了,程序框架基本不用變化吗铐。輕松添加新功能剧劝。
2.1 并排打印三個月份
如果我們需要打印成四行三列的日歷,該怎么辦呢抓歼?我們同樣只需要添加一個打印函數(shù)就可以了讥此。在Month.c中添加函數(shù)如下:
// 并排打印三個月的日歷
void PrintThreeMonth(Month* pMonthLeft, Month* pMonthMid, Month* pMonthRight)
{
int i;
printf("%27s\t", GetMonthName(pMonthLeft));
printf("%27s\t", GetMonthName(pMonthMid));
printf("%27s\n", GetMonthName(pMonthRight));
printf("----------------------------\t----------------------------\t----------------------------\n");
printf("Sun Mon Tue Wed Thu Fri Sat\tSun Mon Tue Wed Thu Fri Sat\tSun Mon Tue Wed Thu Fri Sat\n");
for (i = 0; i < 6; i++)
{
printf("%27s\t", pMonthLeft->_arrayDays[i].buf);
printf("%27s\t", pMonthMid->_arrayDays[i].buf);
printf("%27s\n", pMonthRight->_arrayDays[i].buf);
}
}
之后在Main函數(shù)中修改調用即可:
// 打印12個月的日歷
for (i = 0; i < 12; i++)
{
//PrintMonth(&g_Month[i]);
//PrintTwoMonth(&g_Month[i++], &g_Month[i]);
PrintThreeMonth(&g_Month[i++], &g_Month[i++], &g_Month[i]);
printf("\n");
}
這里需要注意的是,雖然代碼實現(xiàn)沒有問題谣妻,但是命令行程序每行打印字符數(shù)是有限制的萄喳。打印三列會超出寬度限制,導致自動折行打亂排版順序蹋半。大家可以自己試試他巨。
2.2 代碼共享
如需完整的工程代碼,請訪問GitHub中的代碼文件减江。
我是天花板染突,讓我們一起在軟件開發(fā)中自我迭代。
如有任何問題辈灼,歡迎與我聯(lián)系份企。
上一篇:21天C語言代碼訓練營(第八天)
下一篇:21天C語言代碼訓練營(第十天)