C語言#define宏的擴展

使用帶參數的宏定義可完成函數調用的功能,又能減少系統開 銷,提高運行效率。正如C語言中所講,函數的使用可以使程序更加模塊化,便於組織,而且可重複利用,但在發生函數調用時,需要保留調用函數的現場,以便子 函數執行結束後能返回繼續執行,同樣在子函數執行完後要恢復調用函數的現場,這都需要一定的時間,如果子函數執行的操作比較多,這種轉換時間開銷可以忽 略,但如果子函數完成的功能比較少,甚至於只完成一點操作,如一個乘法語句的操作,則這部分轉換開銷就相對較大了,但使用帶參數的宏定義就不會出現這個問 題,因爲它是在預處理階段即進行了宏展開,在執行時不需要轉換,即在當地執行。宏定義可完成簡單的操作,但複雜的操作還是要由函數調用來完成,而且宏定義 所佔用的目標代碼空間相對較大。所以在使用時要依據具體情況來決定是否使用宏定義。


形式參數不能用帶引號的字符串替換。
但是,如果在替換文本中,參數名以#作爲前綴則結果將被擴展爲 由 實際參數 替換 此實際參數的帶引號的字符串。
例如,可以將它與字符串連接運算結合起來編寫一個調試打印宏:
#define dprint(expr) printf(#expr “ = %/n”,expr)
使用語句 dprint(x/y);
調用宏時,該宏將被擴展爲:printf(“x/y”“ = %/n”,x/y);
其中的字符串被連接起來了,這樣便等價於printf(“x/y = %/n”,x/y);

在實際參數中,每個雙引號 “ 將被替換爲 /” ;反斜槓/將被替換爲//,因此替換後的字符串是合法的字符串常量。

預處理運算符 ## 爲宏擴展提供了一種連接實際參數的手段。如果替換文本中的參數與 ## 相鄰,則該參數將被實際參數替換,##與前後的空白符將被刪除,並對替換後的結果重新掃描。
例如,下面定義的宏paste用於連接兩個參數
#define paste(front, back) front ## back
因此,宏調用past(name,1)的結果將建立記號name1.


c語言中沒有swap這個函數,C語言不支持重載,也沒有模版的概念,所以對於每一種類型,都要寫出相應的swap,如
intSwap   (int   *,   int   *);  
longSwap   (long   *,   long   *);  
stringSwap   (char   *,   char   *); 

宏定義swap(t,x,y)以交換t類型的兩個參數(要使用程序塊結構)。
程序如下:
#include <iostream.h>

#define SWAP(t,x,y) /
{/
t temp = *y;/
*y = *x;/
*x = temp;/
}

main()
{
int a = 10, b = 5;
SWAP(int,&a,&b)
cout << a << endl << b<<endl;
}
用/換行,/的意思是說把下一行看作和這行是同一行.換行必須要反斜槓,而且/後面直接回車,不能有空格。

 

 

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x

我們假設:x=1,則有:

A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章