2011年11月30日 星期三

巨集: IN / OUT / INOUT

介紹一組很簡單的巨集
#define IN const
#define OUT
#define INOUT
先談談為什麼需要這樣的巨集



假設我們要寫一個函數, 輸入員工的姓名, 然後取得這名員工的其他資料
這時函數可以宣告這樣:
struct employee_s {
  uint32_t u32id;
  char     sName[64];
  char     sExt[32];
  char     sAddr[128];
  char     sPhone[16];
};

int Get_Employee_By_Name (const char *s_name, struct employee_s *emp);
若使用這個函數的人是有經驗的programmer, 不看文件, 應該就可以推敲出:
  • s_name要放的是輸入的員工名字
  • p_emp是輸出的員工資料
  • return的值是error code, 用來確認是否正常取得資料
但若是菜鳥呢? 可能看到這麼多指標頭就暈了吧!
如果配合這組巨集, 就可以更清楚地標示指標資料的傳遞方向
int Get_Employee_By_Name (IN char *s_name, OUT struct employee_s *emp);
至於INOUT, 是用來標示這組pointer所指向的資料, 同時有輸入輸出效果的

假設哪天有個programmer心血來潮, 想到把上面那個函數改成至這樣:
int Get_Employee_By_Name (struct employee_s *emp);
其中s_name一欄直接放在emp->sName裡面就可以了, 看! 少了一個輸入變數了! 多棒!
但衍生出的問題就是: 如果不看使用文件, 誰會猜到name是要這樣給的啊!
這時候就輪到INOUT出場了
int Get_Employee_By_Name (INOUT struct employee_s *emp);
看! 這樣子多有feel啊! 馬上猜得出來name可能要透過emp來輸入了!

C語言的函數可以有N個輸入, 但只能有1個輸出
若要做到N個輸出, 則必須使用指標來輔助, 這算是C語言的原罪
但問題就如同上面所述, 無法判讀參數中的指標是代表函數的輸入或輸出
透過這些巨集, 就能夠達到補充說明的效果
即使它是個空的巨集

沒有留言:

張貼留言