巨集 macro 定義的簡介

2021-10-10 14:37:07 字數 3022 閱讀 4388

1.1巨集的簡單使用說明

#define square(x) x*x

/**下面我們就來用一下這個巨集

*/printf

("result = %d\n"

,square(5

));/*無可厚非,結果就是5*5=25*/

int a =5;

printf

("result1 = %d\n"

,square

(a+1))

;/*第一眼可能會脫口而出36,

*但是你文字替換一下就是這個樣子x==a+1,所以x*x=a+1 * a+1=11

*///上面的可能不是你的本意,你的本意是要36這個值,就要用下面這個種方式

#undef square

#define square(x) (x)*(x)

printf

("result1 = %d\n"

,square

(a+1))

;/**這樣子我們重新替換一下就是x==a+1,(x)*(x)=(a+1)*(a+1)

*這也算是巨集定義的乙個誤區,需要慎重,不確定的時候建議使用括號包起來

*/

#define x_malloc(type,size) ((type*)malloc(size))

#define malloc

這樣就無法直接在該函式裡呼叫這個系統api了, 但是我們可以通過自己的新定義的萬能api x_malloc來代替系統malloc函式,這樣用起來就方便多了。

1.3其次呢 巨集定義也是可以接收你的function parameter的,如下:

#define  printf(argc,ar**) printf("%s,%d",argc,ar**)

intmain

(char

* argc,

int ar**)

1.4巨集還可以代替結構體來定義乙個結構體變數:

#ifdef member

#undef member

#endif

#define member(type,member) (type member;)

#define struct \

member(int, u4size)\

member(char, u1ch)\

member(bool, bflag)\

intmain

(void

)

/*

*同樣巨集定義也是有邏輯操作的,比如我們判斷是否有定義過這個巨集可以這樣子:

*/#if define symbol

//#ifdef symbol

#endif

#if !define symbol

//ifndef symbol

#endif

/* * 有些時候我們迫不得已要用到下面這種邏輯來隔開不同的code setting

*/#ifdef option1

//implement code for option1

#elif (define option2)

//implement code for option2

#else

//implement code for default setting

#endif

/**還有下面這種同時判斷兩個巨集定義的**/

#if (define option1)&&(define option2)

//implement common code for both of option1 and option2

#elif option1

//implement code only for option1

#elif (define option2)

//implement code only for option2

#else

//implement code for default setting

#endif

在**中我們經常會用到巨集來定義乙個簡單的函式來供我們使用,但是這兩個有什麼區別呢?

我們來簡單列一下巨集和函式區別:

3.1 巨集定義的**較為簡短且都是在預處理的時候就會插入到整個**中,他的生存期和程式一樣;函式適合**較長的使用,每次呼叫會需要重新load同乙個地方的**

3.2巨集因為一直在程式中所以執行速度快,函式每次執行需要重新load相比比較慢

3.3巨集的引數不care型別,甚至可以吧型別當做巨集的引數傳遞,但是函式就不行了(還記得最前面我們舉例的時候有展示乙個malloc的替換嘛,**我們可以直接把型別當做巨集的引數來使用)

3.4巨集對操作符優先順序如果不加括號結果不可預期,但是函式是可以預期

3.5結果返回,巨集的結果返回也有可能不預期,如下面我們的求最大值,但是函式的返回不會造成那種特殊的效果

巨集定義還有乙個***就是它有「持續效果」,這個就是它可以再原來的base上持續進行會改變你的初衷,具體的我們舉個例子來看下:

int x=

5, y=6;

intu4max

(int a,

int b)

#define max(a,b) ((a)>(b)?(a):(b))

/**我們不管呼叫多少次u4max(x++,y++),x和y的增長都是一樣的,第一次呼叫後x=6,y=7,u4max(x++,y++)=7;

*但是max(x++,y++),就不一樣了,第一次呼叫後x=6,y=8,max(x++,y++)=7

*我們把上面的具體展開看下max(x++,y++)=((x++)>(y++)?(x++):(y++))

*這樣就很明顯x和y中有乙個被多加了一次,這也是我們不預期的乙個操作,所以這個持續效果值得我們日常擼碼時候注意

*/

巨集我們就簡單記錄這麼多,使用巨集一定要注意item3裡面的細節,不然很容易造成很多不預期得結果導致不必要的麻煩。

巨集 macro 定義與使用

巨集的定義 巨集的替換與 展開 巨集的替換產生的問題 獲取巨集引數名稱 巨集引數的結合 巨集的取消 巨集定義的換行連線 標準預處理巨集 巨集 macro 是基於 define所實現的另一種預處理功能。與基本的 define定義的是常量相比,巨集 macro 允許多個引數化替換,引數中可以是固定的字串...

gdb 除錯巨集定義macro

c語言中的巨集定義,有著各種好處,當然也有它不好的一面。它實現的三個主要功能是 1 字串替換 2 標頭檔案包含 3 通用 模組的擴充套件 在 除錯時候,除錯巨集定義是比較麻煩的一件事,下面就介紹一種比較簡單的方法。include define max a,b a b a b define min a...

SV 巨集定義(macro)引發的災難

在開發中,用巨集定義可以帶來很多方便,但是使用不當,也會帶來災難,並且不容易debug出來,如下圖所示的程式碼 define switch 64 128 bit 0 define svt axi max data widtn d64 switch 64 128 bit d64 int lane nu...