您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)C語言中typedef有哪些用法,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
C語言中typedef的4種用法:1、為基本數(shù)據(jù)類型定義新的類型名;2、為自定義數(shù)據(jù)類型(結(jié)構(gòu)體、共用體和枚舉類型)定義簡潔的類型名稱;3、為數(shù)組定義簡潔的類型名稱;4、為指針定義簡潔的名稱。
C語言允許用戶使用 typedef 關(guān)鍵字來定義自己習(xí)慣的數(shù)據(jù)類型名稱,來替代系統(tǒng)默認(rèn)的基本類型名稱、數(shù)組類型名稱、指針類型名稱與用戶自定義的結(jié)構(gòu)型名稱、共用型名稱、枚舉型名稱等。
一旦用戶在程序中定義了自己的數(shù)據(jù)類型名稱,就可以在該程序中用自己的數(shù)據(jù)類型名稱來定義變量的類型、數(shù)組的類型、指針變量的類型與函數(shù)的類型等。
例如,C 語言在 C99 之前并未提供布爾類型,但我們可以使用 typedef 關(guān)鍵字來定義一個簡單的布爾類型,如下面的代碼所示:
typedef int BOOL; #define TRUE 1 #define FALSE 0
定義好之后,就可以像使用基本類型數(shù)據(jù)一樣使用它了,如下面的代碼所示:
BOOL bflag=TRUE;
typedef的4種用法
在實際使用中,typedef 的應(yīng)用主要有如下4種。
1、為基本數(shù)據(jù)類型定義新的類型名
也就是說,系統(tǒng)默認(rèn)的所有基本類型都可以利用 typedef 關(guān)鍵字來重新定義類型名,示例代碼如下所示:
typedef unsigned int COUNT;
而且,我們還可以使用這種方法來定義與平臺無關(guān)的類型。比如,要定義一個叫 REAL 的浮點類型,在目標(biāo)平臺一上,讓它表示最高精度的類型,即:
typedef long double REAL;
在不支持 long double 的平臺二上,改為:
typedef double REAL;
甚至還可以在連 double 都不支持的平臺三上,改為:
typedef float REAL;
這樣,當(dāng)跨平臺移植程序時,我們只需要修改一下 typedef 的定義即可,而不用對其他源代碼做任何修改。其實,標(biāo)準(zhǔn)庫中廣泛地使用了這個技巧,比如 size_t 在 VC++2010 的 crtdefs.h 文件中的定義如下所示:
#ifndef _SIZE_T_DEFINED #ifdef _WIN64 typedef unsigned __int64 size_t; #else typedef _W64 unsigned int size_t; #endif #define _SIZE_T_DEFINED #endif
2、為自定義數(shù)據(jù)類型(結(jié)構(gòu)體、共用體和枚舉類型)定義簡潔的類型名稱
以結(jié)構(gòu)體為例,下面我們定義一個名為 Point 的結(jié)構(gòu)體:
struct Point { double x; double y; double z; };
在調(diào)用這個結(jié)構(gòu)體時,我們必須像下面的代碼這樣來調(diào)用這個結(jié)構(gòu)體:
struct Point oPoint1={100,100,0}; struct Point oPoint2;
在這里,結(jié)構(gòu)體 struct Point 為新的數(shù)據(jù)類型,在定義變量的時候均要向上面的調(diào)用方法一樣有保留字 struct,而不能像 int 和 double 那樣直接使用 Point 來定義變量?,F(xiàn)在,我們利用 typedef 定義這個結(jié)構(gòu)體,如下面的代碼所示:
typedef struct tagPoint { double x; double y; double z; } Point;
在上面的代碼中,實際上完成了兩個操作:
1)、定義了一個新的結(jié)構(gòu)類型,代碼如下所示:
struct tagPoint { double x; double y; double z; } ;
其中,struct 關(guān)鍵字和 tagPoint 一起構(gòu)成了這個結(jié)構(gòu)類型,無論是否存在 typedef 關(guān)鍵字,這個結(jié)構(gòu)都存在。
2)、使用 typedef 為這個新的結(jié)構(gòu)起了一個別名,叫 Point,即:
typedef struct tagPoint Point
因此,現(xiàn)在你就可以像 int 和 double 那樣直接使用 Point 定義變量,如下面的代碼所示:
Point oPoint1={100,100,0}; Point oPoint2;
為了加深對 typedef 的理解,我們再來看一個結(jié)構(gòu)體例子,如下面的代碼所示:
typedef struct tagNode { char *pItem; pNode pNext; } *pNode;
從表面上看,上面的示例代碼與前面的定義方法相同,所以應(yīng)該沒有什么問題。但是編譯器卻報了一個錯誤,為什么呢?莫非 C 語言不允許在結(jié)構(gòu)中包含指向它自己的指針?
其實問題并非在于 struct 定義的本身,大家應(yīng)該都知道,C 語言是允許在結(jié)構(gòu)中包含指向它自己的指針的,我們可以在建立鏈表等數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)上看到很多這類例子。那問題在哪里呢?其實,根本問題還是在于 typedef 的應(yīng)用。
在上面的代碼中,新結(jié)構(gòu)建立的過程中遇到了 pNext 聲明,其類型是 pNode。這里要特別注意的是,pNode 表示的是該結(jié)構(gòu)體的新別名。于是問題出現(xiàn)了,在結(jié)構(gòu)體類型本身還沒有建立完成的時候,編譯器根本就不認(rèn)識 pNode,因為這個結(jié)構(gòu)體類型的新別名還不存在,所以自然就會報錯。因此,我們要做一些適當(dāng)?shù)恼{(diào)整,比如將結(jié)構(gòu)體中的 pNext 聲明修改成如下方式:
typedef struct tagNode { char *pItem; struct tagNode *pNext; } *pNode;
或者將 struct 與 typedef 分開定義,如下面的代碼所示:
typedef struct tagNode *pNode; struct tagNode { char *pItem; pNode pNext; };
在上面的代碼中,我們同樣使用 typedef 給一個還未完全聲明的類型 tagNode 起了一個新別名。不過,雖然 C 語言編譯器完全支持這種做法,但不推薦這樣做。建議還是使用如下規(guī)范定義方法:
struct tagNode { char *pItem; struct tagNode *pNext; }; typedef struct tagNode *pNode;
3、為數(shù)組定義簡潔的類型名稱
它的定義方法很簡單,與為基本數(shù)據(jù)類型定義新的別名方法一樣,示例代碼如下所示:
typedef int INT_ARRAY_100[100]; INT_ARRAY_100 arr;
4、為指針定義簡潔的名稱
對于指針,我們同樣可以使用下面的方式來定義一個新的別名:
typedef char* PCHAR; PCHAR pa;
對于上面這種簡單的變量聲明,使用 typedef 來定義一個新的別名或許會感覺意義不大,但在比較復(fù)雜的變量聲明中,typedef 的優(yōu)勢馬上就體現(xiàn)出來了,如下面的示例代碼所示:
int *(*a[5])(int,char*);
對于上面變量的聲明,如果我們使用 typdef 來給它定義一個別名,這會非常有意義,如下面的代碼所示:
// PFun是我們創(chuàng)建的一個類型別名 typedef int *(*PFun)(int,char*); // 使用定義的新類型來聲明對象,等價于int*(*a[5])(int,char*); PFun a[5];
小心使用 typedef 帶來的陷阱
接下來看一個簡單的 typedef 使用示例,如下面的代碼所示:
typedef char* PCHAR; int strcmp(const PCHAR,const PCHAR);
在上面的代碼中,“const PCHAR” 是否相當(dāng)于 “const char*” 呢?
答案是否定的,原因很簡單,typedef 是用來定義一種類型的新別名的,它不同于宏,不是簡單的字符串替換。因此,“const PCHAR”中的 const 給予了整個指針本身常量性,也就是形成了常量指針“char*const(一個指向char的常量指針)”。即它實際上相當(dāng)于“char*const”,而不是“const char*(指向常量 char 的指針)”。當(dāng)然,要想讓 const PCHAR 相當(dāng)于 const char* 也很容易,如下面的代碼所示:
typedef const char* PCHAR; int strcmp(PCHAR, PCHAR);
其實,無論什么時候,只要為指針聲明 typedef,那么就應(yīng)該在最終的 typedef 名稱中加一個 const,以使得該指針本身是常量。
還需要特別注意的是,雖然 typedef 并不真正影響對象的存儲特性,但在語法上它還是一個存儲類的關(guān)鍵字,就像 auto、extern、static 和 register 等關(guān)鍵字一樣。因此,像下面這種聲明方式是不可行的:
typedef static int INT_STATIC;
不可行的原因是不能聲明多個存儲類關(guān)鍵字,由于 typedef 已經(jīng)占據(jù)了存儲類關(guān)鍵字的位置,因此,在 typedef 聲明中就不能夠再使用 static 或任何其他存儲類關(guān)鍵字了。當(dāng)然,編譯器也會報錯,如在 VC++2010 中的報錯信息為“無法指定多個存儲類”。
上述就是小編為大家分享的C語言中typedef有哪些用法了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。