2015年10月2日 星期五

【程式】關於 #define 常數運算的使用



工作上為了便於整理、閱讀,以及修改,會把一些常使用的常數,透過 #define 宣告的方式,定義成便於閱讀的文字。在一次困擾很久的問題解決,發現了一個自己過去常常忽略、沒有養成好習慣的問題:#define常數運算的使用。


來看看底下的範例:


#define    WIDTH               10
#define    HEIGHT              10
#define    DISTANCE_SQUARE     WIDTH*WIDTH + HEIGHT*HEIGHT

INT16 DistanceRatio( INT16 Input )
{
    return    Input/DISTANCE_SQUARE;
}


假設輸入的 Input 值為 200,則這個的範例回傳的值為多少?在 Keil C 環境下,MCU 為某顆ARM 16bits 處理器,得到的值為 300。照原本的設計,會希望得到的值為 1,也就是會照底下的結果運算:

return    (Input/200);


然而 Compiler 編譯出來的結果,卻是將 #define 內的運算當成 Macro 處理,也就是變成了下面的結果:

return    (Input/WIDTH*WIDTH + HEIGHT*HEIGHT);


根據這樣的描述帶入數值,得到 200/10*10 + 10*10 = 300 的答案。想要得到原本的設計答案為 1 結果,則在 #define 內的數值運算,加上括號即可:

#define    WIDTH               10
#define    HEIGHT              10
#define    DISTANCE_SQUARE     ( WIDTH*WIDTH + HEIGHT*HEIGHT )


附帶一提的是,不同的 Compiler 環境不見得會將 #define 內的常數運算當成 Macro 處理,但為了保險起見,加上括號至少確保了內部先行運算的結果。

沒有留言:

張貼留言

熱門文章