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版)"中的部分章節,做個筆記
有興趣可以去構此書來翻閱