程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 關於宏#define使用陷阱總結

關於宏#define使用陷阱總結

編輯:C#入門知識

宏定義發生在預編譯階段,簡單的說本質就是文本替換。使用時,有以下注意事項:

1,用宏定義表達式時,要使用完備的括號

如一下三個例子:

#define ADD(a,b) a+b

#define ADD(a, b) (a + b)

#define ADD(a, b)  (a) +(b)

這三種定義,全部都是不符合要求的。陷阱如下:

在計算ADD(a,b)*ADD(c,d)時,顯然第一種出問題了。

#define MULTIPLE(a, b)  (a*b)  在計算(a+b)*c時,調用MULTIPLE(a+b,c)得到的結果錯誤。

因此一定要使用完備的括號,如下示例:

#define ADD(a,b) ((a) + (b))

2,使用宏定義,不允許參數發生變化,這也就是帶參數的宏定義和函數的區別:

如下測試源碼:

[cpp] 
<span style="font-size:18px;">#include <stdio.h> 
#define sqrt(a) ((a)*(a)) 
int fsqrt(int a) 

    return a*a; 

int main() 

     
    int a = 10, b = 10; 
    int r1, r2; 
     r1 = sqrt(a++); 
     r2 = fsqrt(b++); 
    printf("a = %d, b = %d, r1 = %d, r2 = %d\n", a, b, r1, r2); 
    return 0; 
}</span> 

最終的結果是a = 12; b = 11; r1 = 100; r2 = 100; 以上結果在vc6.0下獲得。之所以a變成12,是因為在替換的時候,a++被執行了兩次。要避免這種行為,就要使宏參數不發生變化。

如:a++; r1 = sqrt(a), 一切就ok了!

3,使用大括號將宏定義包含的多條表達式括起來。

如下示例:

[cpp] 
<span style="font-size:18px;">#include <stdio.h> 
#define INITIAL(a, b)\ 
    a = 0;\ 
    b = 0; 
int main() 

     
    int a[5], b[5] ; 
    int i; 
    for(i=0; i<5; i++) 
    INITIAL(a[i], b[i]); 
 
    printf("a = %d, b = %d\n", a[0], b[0]); 
    return 0; 
}</span> 

結果打印a是正常的,但打印b卻是未初始化的結果。因為簡單的文本替換,不能保證多條表達式都放到for循環體內。(這裡,如果單獨初始化一個變量,沒有for循環時沒有問題的。)上述的宏定義應改為:

[cpp] 
<span style="font-size:18px;">#define INITIAL(a, b)\ 
    {\ 
    a = 0;\ 
    b = 0;\ 
    }</span> 

注意這個“\”號哦,表示下面的一行和當前行在預編譯時被認為在同一行。

最後,再簡單對比下#define和 typedef的區別,#define發生在預編譯階段, typedef發生在編譯階段,可參考http://topic.csdn.net/t/20030810/14/2129718.html。更多細節上的區別,稍後再談。

不對之處,大家多指正。

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved