C語言中define的用法

1、概念

#define命令是C語言中的一個宏定義命令,它用來將一個標識符定義爲一個字符串,該標識符被稱爲宏名,被定義的字符串稱爲替換文本。
該命令有兩種格式:一種是簡單的宏定義,另一種是帶參數的宏定義。
(1)   簡單的宏定義:
 #define   <宏名>  <字符串> 

 例:   #define PI 3.1415926

(2) 帶參數的宏定義 
 #define   <宏名> (<參數表>)   <宏體>

2、常見問題總結

爲了能清楚的理解問題,首先說一下C語言的編譯過程。c語言的編譯經過預處理、編譯、彙編、連接,而宏定義在預處理階段生成,此過程只是純粹的替換和展開沒有任何計算(這個是關鍵)。

(1)下面一段帶來,請寫出其輸出其結果

 #define     3+3
 void main()
 {
   int   temp = N*N;
   printf(“%d”,temp);
 }

分析:展開是在預處理階段完成的,這個階段把替換文本只是看作一個字符串,並不會有任何的計算髮生,在展開時是在宏N出現的地方 只是簡單地使用串3+3來代替N,並不會增添任何的符號,所以對該程序展開後的結果是temp =3+3*3+3,計算後=15,這就是宏替換的實質

(3)帶參數的宏定義

#define   area(x)   x*x
void main()
{
int   y=area(2+2);
printf(“%d”,y);
}
按理說給的參數是2+2,所得的結果應該爲4*4=16,但是錯了,因爲該程序的實際結果爲8,仍然是沒能遵循純粹的簡單替換的規則,又是先計算再替換 了,在這道程序裏,2+2即爲area宏中的參數,應該由它來替換宏定義中的x,即替換成2+2*2+2=8了

#define FUN(a) "a" 

則,輸入FUN(345)會被替換成什麼? 

其實,如果這麼寫,無論宏的實參是什麼,都不會影響其被替換成"a"的命運。 

也就是說,""內的字符不被當成形參,即使它和一模一樣。 

那麼,你會問了,我要是想讓這裏輸入FUN(345)它就替換成"345"該怎麼實現呢? 

請看下面關於#的用法 

#define FUN(a) "a"

則,輸入FUN(345)會被替換成什麼?

其實,如果這麼寫,無論宏的實參是什麼,都不會影響其被替換成"a"的命運。

也就是說,""內的字符不被當成形參,即使它和一模一樣。

那麼,你會問了,我要是想讓這裏輸入FUN(345)它就替換成"345"該怎麼實現呢?

請看下面關於#的用法

 

3、 有參宏定義中#的用法

#define STR(str) #str

#用於把宏定義中的參數兩端加上字符串的""

比如,這裏STR(my#name)會被替換成"my#name"

一般由任意字符都可以做形參,但以下情況會出錯:

STR())這樣,編譯器不會把“)”當成STR()的參數。

STR(,)同上,編譯器不會把“,”當成STR的參數。

STR(A,B)如果實參過多,則編譯器會把多餘的參數捨去。(VC++2008爲例)

STR((A,B))會被解讀爲實參爲:(A,B),而不是被解讀爲兩個實參,第一個是(A第二個是B)。 #define FUN(a) "a"

則,輸入FUN(345)會被替換成什麼?

其實,如果這麼寫,無論宏的實參是什麼,都不會影響其被替換成"a"的命運。

也就是說,""內的字符不被當成形參,即使它和一模一樣。

那麼,你會問了,我要是想讓這裏輸入FUN(345)它就替換成"345"該怎麼實現呢?

請看下面關於#的用法

有參宏定義中#的用法

#define STR(str) #str

#用於把宏定義中的參數兩端加上字符串的""

比如,這裏STR(my#name)會被替換成"my#name"

一般由任意字符都可以做形參,但以下情況會出錯:

STR())這樣,編譯器不會把“)”當成STR()的參數。

STR(,)同上,編譯器不會把“,”當成STR的參數。

STR(A,B)如果實參過多,則編譯器會把多餘的參數捨去。(VC++2008爲例)

STR((A,B))會被解讀爲實參爲:(A,B),而不是被解讀爲兩個實參,第一個是(A第二個是B)。 有參宏定義中#的用法 

#define STR(str) #str 

#用於把宏定義中的參數兩端加上字符串的"" 

比如,這裏STR(my#name)會被替換成"my#name" 

一般由任意字符都可以做形參,但以下情況會出錯: 

STR())這樣,編譯器不會把“)”當成STR()的參數。 

STR(,)同上,編譯器不會把“,”當成STR的參數。 

STR(A,B)如果實參過多,則編譯器會把多餘的參數捨去。(VC++2008爲例) 

STR((A,B))會被解讀爲實參爲:(A,B),而不是被解讀爲兩個實參,第一個是(A第二個是B)。 

形式參數不能用帶引號的字符串替換。
但是,如果在替換文本中,參數名以#作爲前綴則結果將被擴展爲 由 實際參數 替換 此實際參數的帶引號的字符串。
例如,可以將它與字符串連接運算結合起來編寫一個調試打印宏:
#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.

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