C中必須注意的巨集定義細節

2021-09-09 06:48:03 字數 1331 閱讀 2101

1、不能忽略巨集定義的空格,如一例子:

#define f (x) ((x)-1)
當經過預編譯以後,由於巨集定義的作用僅僅是替換的作用,因此,如果使用f(x)的時候,其替換如下:

(x) ((x)-1)(x)
這樣,就遠不能達到要求了。

2、巨集定義與重新命名,若出現以下:`

#define c1 struct foo*

typedef struct foo* c2

c1 a, b;

c2 a, b;

分析:這兩個完全不同。

(1) c1 a, b實質上是等價於struct foo*a,b;這樣a就是乙個結構體指標,而b就是乙個結構體。

(2)c2 a, b;實質上是等價於struct foo* a, b;則兩個都是結構體指標。

3、帶引數巨集的注意事項:由於程式在執行時呼叫函式會產生呼叫開銷,很多時候,如果是比較簡短的功能會用帶參巨集實現,因為巨集定義是在預編譯時進行原地展開,所以不會有呼叫開銷,如:

#include #define max(x,y) (x)>=(y)? (x):(y)

int max(int x, int y)

int main()

執行結果為:

the max is 5(func), 5(define)

#include #define max(x,y) (x)>=(y)? (x):(y)

int max(int x, int y)

int main()

只是把剛剛那個例子的引數換成(2,++i),(2,++j),其它沒有變,其執行結果為:

the max is 3(func), 4(define)

但是執行結果不一樣。原因分析:

(1)對於帶引數函式,傳參過程實質上是先將傳入的引數先複製乙份到棧中作為這個函式裡面區域性變數,所以複製的是乙個數而不是乙個過程(如:傳入++i,則實質是將++i的結果3複製乙份然後傳入y,此後y就是3了),所以在函式max中比較的是2與3的大小,結果為3。

(2)對於帶參巨集定義,由於巨集定義的功能是原地展開,所以上述的巨集定義實質上展開成為了:

(2)>=(++i)? (2):(++i);
所以當執行?前面的時候,會經過一次++i的運算,所以++i的結果是3,而(2)>=(++i)? 的結果是否,所以執行後面的表示式,因此再次執行一次(++i),因此結果也為4了。

巨集的使用及細節注意

1.不帶引數的巨集 一般的使用 define 巨集名 巨集定義字串 其含義為定義乙個名為 巨集名 的巨集,並將該巨集與其名字後的第乙個空格後知道改行結束的所有字串等價起來。然後將這個字串替換隨後程式中任何位置出現的巨集名。2.帶引數的巨集 define 巨集名 引數1,引數2,引數n 巨集定義字串 ...

c 中的巨集定義

一 不帶引數的巨集定義 巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 格式 define 識別符號 字串 其中的識別符號就是所謂的符號常量,也稱為 巨集名 預處理 預編譯 工作也叫做巨集展開 將巨集名替換為字串。掌握 巨集 概念的關鍵是 換 一切以換為前提 做任何事情之前先要換,準確理解之前就要 換...

C中的巨集定義

01 防止乙個標頭檔案被重複包含 ifndef comdef h define comdef h 標頭檔案內容 endif 02 重新定義一些型別,防止由於各種平台和編譯器的不同,而產生的型別位元組數差異,方便移植。typedef unsigned char boolean boolean valu...