typedef
typedef爲一種類型引入新的名字,而不是爲變量分配空間。在某些方面typedef類似於宏文本替換-它並沒有引入新類型,而是爲現有類型取個新名字,但他們之間存在一個關鍵性的區別。typedef看上去跟變量聲明完全一樣,普通的聲明表示“這個名字是一個指定類型的變量”,而typedef關鍵字並不創建一個變量,而是宣稱“這個名字是指定類型的同義詞”。
必須注意typedef的缺點,他同樣具有與其他聲明一樣的混亂語法,同樣可以把幾個聲明塞到一個聲明中去。對於結構,除了可以在書寫時省掉struct關鍵字之外,typedef並不能提供顯著的好處,而少寫一個struct並沒有多大幫助。在任何typedef聲明中,甚至不必把typedef房子啊聲明的開始位置。
關於操作聲明器的一些提示。不要在一個typedef中放入幾個聲明器,如下所示:
typedef int *ptr, (*fun)(), arr[5];
/*ptr 是“指向int 的指針類型”
/*fun 是“指向返回值爲int 的函數指針”
/*arr 是“長度爲5的int 型數組“
千萬不要把typedef嵌到聲明的中間部分,如下所示:
unsigned const long typedef int volatile *kumquat;
typedef int x[10]和define x int[10]的區別
在typedef和宏文本替換之間存在一個關鍵性區別。正確思考這個問題的方法就是把typedef看成是以一種徹底”封裝“類型-在聲明它之後不能再往裏增加別的東西。他和宏的區別體現在兩個方面。
首先,可以用其他類型說明符對宏定義類型名進行擴展,但對typedef所定義的類型名卻不能這樣做。如下所示:
#define peach int
unsigned peach i;/*沒問題*/
typedef int banana;
unsigned banana i;/*錯誤!非法*/
其次,在連續幾個變量聲明中,用typedef定義的類型能夠保證聲明中所有的變量均爲同一種類型,而用define定義的類型則無法保證,如下所示:
#define int_ptr int *
int_ptr chalk,cheese;
經過宏擴展,第二行變爲:
int *chalk,cheese;
這使得chalk和cheese成爲不同的類型;chalk是一個指向int 類型的指針,而cheese則是一個int。相反,下面的代碼中:
typedef char* char_ptr;
char_ptr Bentley,Rolls_Royce;
Bentley和Rolls_Royce的類型依然吸納共同。雖然前面的類型名變了,但他們的類型相同,都是指向char的指針。
操作typedef的提示
不要爲了方便起見對結構使用typedef。這樣做的唯一好處就是少寫一個struct。typedef應該用在:
- 數組、結構、指針以及函數的組合類型;
- 可移植類型。比如當你需要一種至少20比特類型時,可以對它進行typedef操作typedef的提示聲明。這樣,當把代碼移植到不同的平臺時,要選擇正確的類型如 short,int,long,時,只要在typedef中進行修改就可以了,無需對每個聲明都加以修改。
- typedef也可以爲後面的強制類型轉換提供一個簡單的名字。