從「精確包含頭文件」(參見《精確包含頭文件》)這一編程好習慣中能夠獲得另一個好習慣,那就是就是儘量保證模塊的對外頭文件簡浩。
一般的編程習慣是將全部的數據結構都放在頭文件中,且這個頭文件也包含模塊接口函數的原型聲明,圖1就是一個例子。請注意其中的62~69行所定義的bucket_t結構,這一結構是模塊的內部數據結構,也就是說從模塊的外部來看根本不知道這一結構的存在,這從76~83行模塊全部函數的原型聲明中能夠看出,由於這些函數的參數和返回類型中都沒有引用它。
編程
timer.h
00037: typedef struct tag_timer *timer_handler_t;
00038:
00039: // callback function for timer expiration
00040: typedef error_t (*expiration_cb_t)(timer_handler_t _handler, void *_arg);
00049:
00050: typedef struct tag_timer
00051: {
00052: ...
00060: } timer_instance_t;
00061:
00062: typedef struct
00063: {
00064: ...
00069: } bucket_t;
00070:
00076: int timer_lock_init ();
00077: void timer_fire ();
00078: error_t timer_alloc (timer_handler_t *_p_handler,
00079: msecond_t _duration,expiration_cb_t _cb, const char *_name);
00080: error_t timer_free (timer_handler_t _handler);
00081: error_t timer_start (timer_handler_t _handler, void *_arg);
00082: error_t timer_stop (timer_handler_t _handler);
00083: void timer_dump ();
圖1
bucket_t結構的定義放在timer.h頭文件中合適嗎?從簡化模塊頭文件的角度來講是不合適的,由於外部在使用定時器模塊時並不須要使用到bucket_t結構,所以應當將它從timer.h中移出去。有兩種作法,一是將這一結構放入到timer.c文件中,或者定義一個只用來被timer.c包含的模塊私有頭文件。當內部數據結構只須要被一個.c文件引用時,前一種方式更簡單,這能夠省去新增長一個文件的麻煩;可是,當有多個.c文件須要使用它時則第二種方法更合適。
簡化模塊頭文件的目的就是爲了讓其它模塊的.c文件在包含它時,能夠作到所需編譯的文件大小最小化,從而提升程序的編譯效率,其緣由在「精確包含頭文件」這一編程發習慣中有所闡述。
數據結構