1. 程式人生 > >[轉] #define用法詳解 #define用法詳解

[轉] #define用法詳解 #define用法詳解

#define用法詳解

 

1.#define 的作用

  在C或C++語言源程式中允許用一個識別符號來表示一個字串,稱為“巨集”。被定義為“巨集”的識別符號稱為“巨集名”。在編譯預處理時,對程式中所有出現的“巨集名”,都用巨集定義中的字串去代換,這稱為“巨集代換”或“巨集展開”。巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。

  在C或C++語言中,“巨集”分為有引數和無引數兩種。

2. 無參巨集定義

  無參巨集的巨集名後不帶引數。

  其定義的一般形式為:

  #define 識別符號 字串

  其中的“#表示這是一條預處理命令。凡是以“#”開頭的均為預處理命令。“define”為巨集定義命令。“識別符號”為所定義的巨集名。“字串”可以是常數、表示式、格式串等。

  例如:

  #define M (a+b)

  它的作用是指定識別符號M來代替表示式(a+b)。在編寫源程式時,所有的(a+b)都可由M代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(a+b)表示式去置換所有的巨集名M,然後再進行編譯。

  程式1:

複製程式碼
#define M (a+b)

  main(){

  int s,y;

  printf("input a number: ");

  scanf("%d",&y);

  s=M*M;

  printf("s=%d\n",s);
}
複製程式碼

  上例程式中首先進行巨集定義,定義M來替代表達式(a+b),在 s= M * M 中作了巨集呼叫。在預處理時經巨集展開後該語句變為: S=(a+b)*(a+b)

  但要注意的是,在巨集定義中表達式(a+b)兩邊的括號不能少。否則會發生錯誤。

  如當作以下定義後:#difine M (a)+(b)

  在巨集展開時將得到下述語句:S= (a)+(b)*(a)+(b)

  對於巨集定義還要說明以下幾點:

  1. 巨集定義是用巨集名來表示一個字串,在巨集展開時又以該字串取代巨集名,這只是一種簡單的代換,字串中可以含任何字元,可以是常數,也可以是表示式,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。

  2. 巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。

  3. 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用#undef命令。

3. 帶參巨集定義

  c語言允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。

  帶參巨集定義的一般形式為:

  #define 巨集名(形參表字串

  在字串中含有各個形參。

  帶參巨集呼叫的一般形式為:

  巨集名(形參表)

  例如:

  #define M(y) ((y)*(y)+3*(y)) /*巨集定義*/

  ....

  k=M(5); /*巨集呼叫*/

  ....

  在巨集呼叫時,用實參5去代替形參y,經預處理巨集展開後的語句為:

  k=5*5+3*5

  程式2:

複製程式碼
#define MAX(a,b) (a>b)?a:b

  main(){

  int x,y,max;

  printf("input two numbers: ");

  scanf("%d%d",&x,&y);

  max=MAX(x,y);

  printf("max=%d\n",max);

  }
複製程式碼

  上例程式的第一行進行帶參巨集定義,用巨集名MAX表示條件表示式(a>b)?a:b,形參a,b均出現在條件表示式中。程式第七行max=MAX(x,y)為巨集呼叫,實參x,y,將代換形參a,b。巨集展開後該語句為:

  max=(x>y)?x:y;

  用於計算x,y中的大數。

 4.防止重複定義

#define 條件編譯

  標頭檔案(.h)可以被標頭檔案或C檔案包含;

  重複包含(重複定義)

  由於標頭檔案包含可以巢狀,那麼C檔案就有可能包含多次同一個標頭檔案,就可能出現重複定義的問題的。

  通過條件編譯開關來避免重複包含(重複定義)

  例如

  #ifndef __headerfileXXX__

  #define __headerfileXXX__

  …

  檔案內容

  …

  #endif

1.#define 的作用

  在C或C++語言源程式中允許用一個識別符號來表示一個字串,稱為“巨集”。被定義為“巨集”的識別符號稱為“巨集名”。在編譯預處理時,對程式中所有出現的“巨集名”,都用巨集定義中的字串去代換,這稱為“巨集代換”或“巨集展開”。巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。

  在C或C++語言中,“巨集”分為有引數和無引數兩種。

2. 無參巨集定義

  無參巨集的巨集名後不帶引數。

  其定義的一般形式為:

  #define 識別符號 字串

  其中的“#表示這是一條預處理命令。凡是以“#”開頭的均為預處理命令。“define”為巨集定義命令。“識別符號”為所定義的巨集名。“字串”可以是常數、表示式、格式串等。

  例如:

  #define M (a+b)

  它的作用是指定識別符號M來代替表示式(a+b)。在編寫源程式時,所有的(a+b)都可由M代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(a+b)表示式去置換所有的巨集名M,然後再進行編譯。

  程式1:

複製程式碼
#define M (a+b)

  main(){

  int s,y;

  printf("input a number: ");

  scanf("%d",&y);

  s=M*M;

  printf("s=%d\n",s);
}
複製程式碼

  上例程式中首先進行巨集定義,定義M來替代表達式(a+b),在 s= M * M 中作了巨集呼叫。在預處理時經巨集展開後該語句變為: S=(a+b)*(a+b)

  但要注意的是,在巨集定義中表達式(a+b)兩邊的括號不能少。否則會發生錯誤。

  如當作以下定義後:#difine M (a)+(b)

  在巨集展開時將得到下述語句:S= (a)+(b)*(a)+(b)

  對於巨集定義還要說明以下幾點:

  1. 巨集定義是用巨集名來表示一個字串,在巨集展開時又以該字串取代巨集名,這只是一種簡單的代換,字串中可以含任何字元,可以是常數,也可以是表示式,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。

  2. 巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。

  3. 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用#undef命令。

3. 帶參巨集定義

  c語言允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。

  帶參巨集定義的一般形式為:

  #define 巨集名(形參表字串

  在字串中含有各個形參。

  帶參巨集呼叫的一般形式為:

  巨集名(形參表)

  例如:

  #define M(y) ((y)*(y)+3*(y)) /*巨集定義*/

  ....

  k=M(5); /*巨集呼叫*/

  ....

  在巨集呼叫時,用實參5去代替形參y,經預處理巨集展開後的語句為:

  k=5*5+3*5

  程式2:

複製程式碼
#define MAX(a,b) (a>b)?a:b

  main(){

  int x,y,max;

  printf("input two numbers: ");

  scanf("%d%d",&x,&y);

  max=MAX(x,y);

  printf("max=%d\n",max);

  }
複製程式碼

  上例程式的第一行進行帶參巨集定義,用巨集名MAX表示條件表示式(a>b)?a:b,形參a,b均出現在條件表示式中。程式第七行max=MAX(x,y)為巨集呼叫,實參x,y,將代換形參a,b。巨集展開後該語句為:

  max=(x>y)?x:y;

  用於計算x,y中的大數。

 4.防止重複定義

#define 條件編譯

  標頭檔案(.h)可以被標頭檔案或C檔案包含;

  重複包含(重複定義)

  由於標頭檔案包含可以巢狀,那麼C檔案就有可能包含多次同一個標頭檔案,就可能出現重複定義的問題的。

  通過條件編譯開關來避免重複包含(重複定義)

  例如

  #ifndef __headerfileXXX__

  #define __headerfileXXX__

  …

  檔案內容

  …

  #endif