1. 程式人生 > >巨集定義#Define和Typedef的用法和區別

巨集定義#Define和Typedef的用法和區別

一:各自的定義

  (一)

  Typedef 本身是一種儲存類的關鍵字,在計算機程式語言中用來為複雜的宣告定義簡單的別名。

  Typedef 的含義:

  1. 找到你所要宣告的通用格式。例如這裡申明 inta[4],b[4],c[4],只有a,b,c不同,但是他們有相同的申明模式 int<名字>[4];
  2. 用你想要申明的新型別名代替通用格式中的變化部分。例如這裡就是用新型別int_array代替a,b,c所在的位置,再在前面加上Typedef符號
  3. 以後你想申明處在上面int_array位置的a,b,c型別時,就可以用:int_array a,b,c;

所以在程式中,可能需要為某些整數定義一個別名,我們就可以利用預處理指令#define來完成。

用途一:

  定義一種型別的別名,而不只是簡單的巨集替換。可以用作同時宣告指標型的多個物件。

        比如:char* pa, pb;        // 這多數不符合我們的意圖,它只聲明瞭一個指向字元變數的指標和一個字元變數;

  以下則可行:

  typedef char* PCHAR; // 一般用大寫

  PCHAR pa, pb; // 可行,同時聲明瞭兩個指向字元變數的指標

  雖然:char *pa, *pb;

       也可行,但相對來說沒有用typedef的形式直觀,尤其在需要大量指標的地方,typedef的方式更省事。

  用途二:

  用typedef來定義與平臺無關的型別。

  比如定義一個叫 REAL 的浮點型別,在目標平臺一上,讓它表示最高精度的型別為:

  typedef long double REAL;

  在不支援 long double 的平臺二上,改為:

  typedef double REAL;

  在連 double 都不支援的平臺三上,改為:

  typedef float REAL;

  也就是說,當跨平臺時,只要改下 typedef 本身就行,不用對其他原始碼做任何修改。

  標準庫就廣泛使用了這個技巧,比如size_t。

  另外,因為typedef是定義了一種型別的新別名,不是簡單的字串替換,所以它比巨集來得穩健(雖然用巨集有時也可以完成以上的用途)。

  用途三:

  為複雜的宣告定義一個新的簡單的別名。方法是:在原來的聲明裡逐步用別名替換一部分複雜宣告,如此迴圈,把帶變數名的部分留到最後替換,得到的就是原宣告的最簡化版。舉例:

  1. 原宣告:int *(*a[5])(int, char*);

  變數名為a,直接用一個新別名pFun替換a就可以了:

  typedef int *(*pFun)(int, char*);

  原宣告的最簡化版:

  pFun a[5];

  2. 原宣告:void (*b[10]) (void (*)());

  變數名為b,先替換右邊部分括號裡的,pFunParam為別名一:

  typedef void (*pFunParam)();

  再替換左邊的變數b,pFunx為別名二:

typedef void (*pFunx)(pFunParam);

 

(二)巨集定義#define又稱為巨集代換、巨集替換,簡稱“巨集

格式:

1.

#define識別符號字串

其中的識別符號就是所謂的符號常量,也稱為巨集名”,

例如:

#definePi3.1415926

就是把程式中出現的Pi全部換成3.1415926

2.除了一般的字串替換,還要做引數代換

格式:

#define巨集名(引數表)字串

例如:#defineS(a,b)a*b

area=S(3,2)

第一步被換為area=a*b;,第二步被換為area=3*2;

類似於函式呼叫

簡單的巨集定義有如下格式:

[#define指令 (簡單的巨集)]  #define 識別符號替換列表

當前處理器遇到一個 巨集定義時,會做一個“識別符號”代表“替換列表”的記錄,在檔案後面的內容中,不管識別符號在任何位置出現,前處理器都會用替換列表代替它。

簡單的巨集主要用來定義 明示常量的東西,使用巨集,我們可以給數值,字元,和字串命名。

#define STE_LEN   80

#define TRUE   1

#define FALSE   0

#define PI    3.14159

#define CR    ‘\r’

#define  EOS   ‘\0’

二:區別

Typedef 和巨集定義的區別:

Define是一種智慧替換,而typedef是告訴編譯器,為這個型別取了一個別名,而不是像巨集一樣是一種文字替換了。

使用define:

#define Mytype int*

Mytype a,b; //此時出現差異,a為指向int的指標變數,而b為int變數

使用typedef:

   Typedef int *mytype;

Mytype a,b; //a,b均為指向int 的指標變數

由此可見,當我們在函式中,需要連續宣告多個像這種指標變數時,則應該使用typedef,用typedef定義的型別能夠保證宣告中所有的變數均為同一型別。

還有在 const關鍵字修飾下也不同:

n=2;

const Mytype a;

a=&n;

//這時候就出現錯誤了,因為const 修飾的是int,此時a是一個指向常量的指標;

Const mytype b=n;

//此時const修飾的是int*,b是一個常指標;