C語言中帶參數的宏


帶參數的宏定義有如下的格式:

【#define 指令----帶參數的宏】 #define 標識符(x1,x2,……,xn)

其中  x1,x2,……xn是標志符(宏的參數)

注意:在宏的名字和括號之間必修沒有空格。

如果有空格,預處理會認為是在定義一個簡單的宏,其中(x1,x2,……,xn)是替換列表的一部分

當預處理器遇到一個帶參數的宏,會將定義存儲起來以便以后使用。在后面的程序中,如果任何地方出現了標識符(y1,y2……,yn)格式的宏調用(其中y1,y2, ……yn是一些列標記),預處理器會使用替換列表替代,並使用yi替換xi

e.g. 假如我們定義了如下的宏:

#define MAX(x,y)  ((x)>(y) ? (x) : (y))

#define IS_EVEN(n)  ((n)%2==0)

下面的例子是一個更加復雜的宏:

#define TOUPPER(c)  ('a'<=(c) && (c)<='z' ? (c)-'a'+'A' : (c))

帶參數的宏可以包含空的參數列表,如下所示:

#define getchar() getc(stdin)

空的參數列表不是一定確實需要,但可以使getchar更像一個函數

使用帶參數的宏替代實際的函數有兩個優點:

  • 程序可能會稍微快些。一個函數調用在執行時通常會有些額外開銷----存儲上下文信息、復制參數的值等。而一個宏的調用則沒有這些運行開銷
  • 宏會更“通用”。與函數的參數不同,宏的參數沒有類型。因此,只要預處理后的程序依然合法的,宏可以接受任何類型的參數。 e.g.我們可以使用MAX宏從兩個數中選出較大的一個,數的類型可以是:int,long int,float,double等等
  • 編譯后的代碼通常會變大。每一處宏調用都會導致插入宏的替換列表,由此導致程序源代碼增加(因此編譯后的代碼變大)。宏使用得越頻繁,這種效果就越明顯。當宏調用嵌套時,這個問題會相互疊加從而使程序更加復雜。e.g. n=MAX(i,MAX(j,k));

下面是預處理后的這條語句:      

n=((i)>(((j)>(k)?(j):(k)))?(i):(((j)>(k)?(j):(k))));

 

  • 宏參數沒有類型檢查。
  • 無法用一個指針來指向一個宏
  • 宏可能會不止一次地計算它的參數。函數對它的參數只會計算一次,而宏可能會計算兩次甚至更多。如果參數有副作用,多次計算參數的值可能會產生意外的結果

考慮下面的例子,其中MAX的一個參數有副作用:

n=MAX(i++, j)

下面是這條語句在預處理之后的結果:

n=((i++) >(j)?(i++):(j));

帶參數的宏不僅適用於模擬函數的調用,他們特別經常被作為模板,來處理我們經常要重復書寫代碼段:

e.g.我們可以使用

#define PRINT_INT(x)  printf("%d\n",x);

使得PRINT_INT(x)代替每次使用的printf("%d\n",x);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM