typedef 是C語言提供的一種高級數據特性,它能幫助我們給某一類型創建我們自己的名字,方便我們編碼和使用。 ...
最近在複習數據結構時,經常看到 typedef 的身影,但始終不清楚 typedef 的用法具體時怎麼樣的,特地查閱《C Primer Plus 第5版》,並將查到的內容寫出來供大家溝通學習。
typedef 工具是一種高級數據特性,它使你能夠為某一類型創建您自己的名字。在這個方面,它和 #define 相似,但是它們具有3個不同之處:
- 與 #define 不同,typedef 給出的符號名稱僅限於對類型,而不是對值。
- typedef 的解釋由編譯器,而不是由解釋器執行。
- 雖然它的範圍有限,但在受限範圍內,typedef 比 #define 更靈活。
我們來看看 typedef 是怎樣工作的。假設要對1位元組的教值使用術語BYTE,您只須像定義一個char變數那樣定義BYTE,然後在這個定義前面加上關健字 typedef,如:
typedef unsigned char BYTE;
隨後您就可以使用 BYTE 來定義變數了:
BYTE x, y[10], *z;
該定義的作用域取決於 typedef 語句所在的位置。如果定義是在一個函數內部,它的作用域就縣局部的,限定在那個函數里。如果定義是在函教外部,它將具有全局作用域。
通常,這些定義使用大寫字母,以提醒用戶這個類型名稱實際上是個符號縮寫。不過,您也可以使用小寫字母:
typedef unsigned char byte;
管理變數名的同樣規則也用來管理 typedef 使用的名字。
為一個已經存在的類型創建一個名字可能看起來沒有什麼必要,然而這可能會是有用的。在前面的例子中,使用BYTE來代替 unsigned char 有助於說明您打算用 BYTE 變數來表示數值而非字元編碼。使用 typedef 也有助於增加可移植性。例如,我們已經提到過表示 sizeof 運算符返回類型的size_t 類型,以及表示函數 time() 的返回值類型的 time_t 類型。C標準規定 sizeof 和 time() 應返回整數類型,但它留給具體的實現來決定到底是哪種整數類型。不進行指定的原因是ANSI C委員會覺得沒有一個對所有電腦平臺來說都是最好的選擇。因此他們提出一個新類型名稱,如 time_t,讓C實現使用 typedef 來把這個名稱設定為某種特定的數據類型。這樣,他們可以提供下列通用原型:
time_t time(time_t *);
在一個系統上,time_t 可能是 unsigned int 類型;在另一個系統上,它可能是 unsigned long 類型。只要包含了 time.h 頭文件,程式就可以訪問適當的定義,您也可以在代碼中聲明 time_t 變數。
使用 #define 可以實現 typedef 的部分功能。例如:
#define BYTE unsigned char
這使預處理器用 unsigned char來代替 BYTE。但也有 #define 實現不了的功能,如下例所示:
typedef char* STRING;
如果沒有關鍵字 typedef,該例將 STRING 識別為一個 char 指針。有了這個關鍵字,使STRING成為 char 指針的標識符。因此:
STRING name, sign;
意思是:
char * name, * sign;
但是,假設這樣做:
#define STRING char *;
那麼:
STRING name, sign;
將會被翻譯成下麵的形式:
char *name,sign;
在這種情況下,只有 name 是一個指針。
也可以對結構使用 typedef:
typedef struct complex{ float real; float imag; }COMPLEX;
這樣您就可以用類型 COMPLEX 代替 struct complex 來表示覆數。使用 typedef 的原因之一是為經常出現的類型創建一個方便的、可識別的名稱。例如,在前面的例子中,許多人都願意使用 STRING 或與其等價的標記。
使用 typedef 來命名一個結構類型時,可以省去結構的標記:
typedef struct{ double x; double y; }rect;
假設像下麵這樣使用 typedef 定義的類型名:
rect r1 = {3.0, 6.0}; rect r2; r2 = r1;
這被翻譯成:
1 struct{ 2 double x; 3 double y; 4 }r1 = {3.0, 6.0}; 5 6 struct{ 7 double x; 8 double y; 9 }r2; 10 r2 = r1;
如果兩個結構的聲明都不使用標記,但是使用同樣的成員(成員名和類型鄯匹配),那麼 C 認為這兩個結構具有同樣的類型,因此將 r1 賦給 r2 是一個正確的操作。
使用 typedef 的另一個原因是 typedef 的名稱經常被用於複雜的類型。例如:
typedef char (* FRPTC ()) [5];
這把 FRPTC 聲明為一個函數類型,該類型的函數返回一個指向含有5個元素的 char 數組的指針(請參見下麵將要討論的一些奇特的聲明)。
當使用 typedef 時,要記住它並不創建新的類型,它只是創建了便於使用的標簽。這意味著,例如,我們創建的 STRING 關型的安量可以作為參數傳遞給需要 char 指針類型參數的函數。
通過結構、聯合和 typedef,C 提供了有效和方便地處理數據的工具。
作者:耑新新,發佈於 博客園
轉載請註明出處,歡迎郵件交流:[email protected]