巨集定義與使用分析

2021-06-16 15:17:40 字數 2510 閱讀 7388

巨集定義常量:

#define巨集定義常量可以出現在**的任何地方

#define從本行開始,之後的**都可以使用這個巨集常量

以上巨集定義都正確

最後乙個巨集定義採用了接續符「\」,等同於#define path_3  d:\delphi\ctopic3.ppt

巨集定義表示式

#define表示式有函式呼叫的假象,卻不是函式

#define表示式可以比函式更強大

#define表示式比函式更容易出錯

例1:#define sum(a,b)  (a)+(b)

printf("%d\n",sum(1,2) * sum(1,2));   //輸出為5

本意是要求3*3=9,但是巨集定義只是簡單的替換,在預編譯階段巨集展開後為printf("%d\n", (1)+(2)*(1)+(2));,所有輸出為5,這時需要在巨集定義表示式最外層加上括號為 #define sum(a,b)  ((a)+(b)),這樣巨集展開後為printf("%d\n", ( (1)+(2))*((1)+(2)) );這樣就可以輸出想要的結果。

所以要搞定#define巨集,不要吝嗇括號。

例2:#define min(a,b)  ( (aint min(int  a, int  b)

return  ( (aint i = 1, j = 5;

printf("%d\n",  min(i++, j));   //輸出為2

printf("%d\n",  min(i++, j));   //輸出為1

因為printf("%d\n",  min(i++, j))巨集展開後是printf("%d\n",  ( (i++ < 5) ? (i++) : (5) )),i會自增兩次,輸出第二個i++的值就是2

而printf("%d\n",  min(i++, j))呼叫min函式,只是把i++和j的值即1和5的值穿進去了,所以輸出還是1。

注意:巨集函式被呼叫時是以實參代換形參,而不是「值傳送」

例3:#define dim(array)  (sizeof(array) / sizeof(*array))

int dim(array)

return sizeof(array) / sizeof(*array);

int a = ;

printf("%d\n", dim(a));   //輸出1  

printf("%d\n", dim(a));   //輸出5

c語言函式弱點,陣列引數會退化為乙個指標,所以函式dim(array)中sizeof(array)就是指標所占用的空間大小,而不是陣列所占用的空間大小

因此,此處巨集定義dim(array) 的功能遠比函式要強大,沒有任何乙個函式能夠實現這個巨集的功能去檢測乙個陣列裡面有多少陣列元素。

巨集表示式與函式對比:

巨集表示式在預編譯期被處理,編譯器不知道巨集表示式的存在;

巨集表示式用「實參」完全替代形參,不進行任何運算;

巨集表示式沒有任何的「呼叫」開銷;

巨集表示式中不能出現遞迴定義,如:

#define fac(n)  ( (n>0) ? (fac(n-1) + 1) : 0 ); 

printf("%d\n", fac(20)); 

預編譯巨集展開後是printf("%d\n",  ( (20>0) ? (fac(20-1) + 1) : 0 ));此時會認為fac是函式,再經過編譯後彙編**中會出現call fac語句,把fac當函式了,隨後彙編器彙編時就會報錯,因為找不到fac。

#undef:

巨集定義的常量或表示式是否有作用域限制?

int f1(int a, int b)

int f2(int a, int b, int c)

printf("%d\n", f1(2, 1));      //可以正常輸出1

printf("%d\n", f2(5, 3, 2));  //輸出2,說明函式f1裡面的巨集定義可以在函式f2中正常使用,如果函式f1最後再加一句#undef _min_(a, b);,f2中的巨集就不起作用了。

所以,#define巨集定義常量可以出現在**的任何地方,#define巨集的作用域從檔案中的定義點開始,直到用#undef指令取消巨集為止,或直到檔案尾為止。

巨集定義中的空格:

#define sum    (x)   (x)+ (x) 

這還是定義的巨集函式sum(x)嗎?顯然不是。編譯器認為這是定義了乙個巨集:sum,其代表的是 (x)   (x)+ (x) 。為什麼會這樣呢?其關鍵問題還是在於sum 後面的這個空格。所以在定義巨集的時候一定要注意什麼時候該用空格,什麼時候不該用空格。這個空格僅僅在定義的時候有效,在使用這個巨集函式的時候,空格會被編譯器忽略掉。也就是說,定義好的巨集函式sum(x)的sum和(x)之間不能有空格 ,在使用的時候在sum 和(x)之間留有空格是沒問題的。比如:sum(3) 、sum    (3)和sum      (3)的意思是一樣的。

巨集定義及使用分析

巨集定義及使用分析 1 巨集定義理解 1 表達形式 define 標示符 字串 2 巨集定義是用巨集名來表示乙個字串,是一種簡單的代換,字串中可以 含任何字元,可以是常數,也可以是表示式,預處理時不作任何檢查,編譯時才能查出錯誤。3 巨集定義不是說明或語句,在行末不需要加分號 4 巨集定義必須寫在函...

19 巨集定義使用分析

巨集開始給我的兩個印象 1 可以用來定義常量 2 定義 塊 1 c語言中的巨集定義 define 是預處理器處理的單元實體之一 define 定義的巨集可以出現在程式的任意位置 define 定義之後的 都可以使用這個巨集 2 定義巨集常量 define 定義的巨集常量可以直接使用 define 定...

巨集定義與使用

下面這些巨集常量定義正確嗎?define error 1 define pathl d test test.c define path2 d test test.c define path3 d test 預處理器不會進行語法檢查只是簡單的文字替換,即這些巨集定義都正確 例子1 巨集表示式的使用 i...