關於宏#define使用陷阱總結

來源:互聯網
上載者:User

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

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,使用宏定義,不允許參數發生變化,這也就是帶參數的宏定義和函數的區別:

如下測試源碼:

#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;}

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

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

3,使用大括弧將宏定義包含的多條運算式括起來。

如下樣本:

#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;}

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

#define INITIAL(a, b)\{\    a = 0;\b = 0;\}

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

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

不對之處,大家多指正。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.