C與言筆記-宏定義 define 的注意事項與陷阱
這幾篇會對宏定義#define做個筆記:
-------------------------------------------------------------------------------------------
宏定義主要執行文本交換,以下有些陷阱要避開:
陷阱1:
執行
--------------------
執行
結果不會是預期的8而是10
因為替換後變成
printf("double(1+1):%d\n",1+1*8);
為了預防這種錯誤,最好事都加上括號()
最常見的宏定義就是:
---------------------------------------------------------
陷阱2:宏定義的兩端要加上大括號{}
這是一種常見的宏定義陷阱
---------------------------------------------------------
陷阱3:就算加上大括號還是有陷阱在裡面要注意!!
解決辦法只有一個,就是加上只做一次的do -while迴圈:
陷阱4: 有break的情況下仍然有陷阱
本章節是整理"C成續設計新思維(第2版)"中的部分章節,做個筆記
有興趣可以去構此書來翻閱
-------------------------------------------------------------------------------------------
宏定義主要執行文本交換,以下有些陷阱要避開:
陷阱1:
#define double(x) 2*x
執行
int main(void) { printf("double(4):%d\n",double(4)); }結果為8
--------------------
執行
int main(void) { printf("double(1+1):%d\n",double(1+1)); }
結果不會是預期的8而是10
因為替換後變成
printf("double(1+1):%d\n",1+1*8);
為了預防這種錯誤,最好事都加上括號()
#define double(x) (2*x)
最常見的宏定義就是:
#define max(a,b) ((a)>(b)?(a):(b))
---------------------------------------------------------
陷阱2:宏定義的兩端要加上大括號{}
#define increament(a,b) \ (a)++; \ (b)++;沒有加大括號,如果把他放在if後面會有此風險:
int x=1,y=0; if(x>y) increament(x,y);展開的話變成:
int x=1,y=0; if(x>y) (x)++; (y++);
這是一種常見的宏定義陷阱
---------------------------------------------------------
陷阱3:就算加上大括號還是有陷阱在裡面要注意!!
#define increase(a,b) {\ (a)++; \ (b)++; \ } if(a>b) increase(a,b); else return 0;展開變成:
if(a>b){ (a)++; (b)++; }; else rerutn 0;可能導致變易錯誤,因為else前面有一個分號
解決辦法只有一個,就是加上只做一次的do -while迴圈:
#define increase(a,b) do{ \ (a)++; \ (b)++; \ }while(0)
陷阱4: 有break的情況下仍然有陷阱
#define Assert_(ecpression,action) do{ \ if(!(expression)) action; }while(0) double total=0; double array[100]; for(int i=0;i<100;i++) { Assert_(!isnan(array[i])),break;); total+=array_[i]; }break被嵌入do-while裡面,這種情況就不能用do-while來包裝了!!
本章節是整理"C成續設計新思維(第2版)"中的部分章節,做個筆記
有興趣可以去構此書來翻閱