巨集定義#Define和Typedef的用法和區別
一:各自的定義
(一)
Typedef 本身是一種儲存類的關鍵字,在計算機程式語言中用來為複雜的宣告定義簡單的別名。
Typedef 的含義:
- 找到你所要宣告的通用格式。例如這裡申明 inta[4],b[4],c[4],只有a,b,c不同,但是他們有相同的申明模式 int<名字>[4];
- 用你想要申明的新型別名代替通用格式中的變化部分。例如這裡就是用新型別int_array代替a,b,c所在的位置,再在前面加上Typedef符號
- 以後你想申明處在上面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.
其中的識別符號就是所謂的符號常量,也稱為“巨集名”,
例如:
#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是一個常指標;