C語言中的關鍵字-typedef之理解和使用
20170726 --iRonMan
C語言允許使用者使用typedef關鍵字來定義自己習慣的資料型別名稱,來替代系統預設的基本型別名稱。
舉個簡單的例子,C語言在C99之前並未提供布林型別,但我們可以使用typedef關鍵字來定義一個簡單的布林型別,如下
typedef int BOOL; //給int基本型別去了新名字BOOL
#define TRUE 1 //定義TRUE為1,即可以用TRUE來表示1(為真)
#define FALSE 0
定義好之後就可以像使用基本型別一樣使用定義的BOOL
BOOL bflag=TRUE; //等價於 int bflag=1
學習C語言,應該對typedef的四種應用形式有所掌握。
1.為基本資料型別定義新的型別名
定義與平臺無關的型別,即不管在什麼平臺上都可以使用這個新的型別名,有利於跨平臺移植程式
比如,要定義一個叫REAL的浮點型別,在目標平臺1上,讓它表示最高精度的浮點型別,即
typedef long double REAL;
在不支援long double 的平臺2上,改為
typedef double REAL;
甚至還可以連double都不支援的平臺3上,改為
typedef float REAL;
這樣,當移植程式時,我們只需要修改一下typedef 的定義即可,而不用對原始碼中出現的同種資料型別一個一個修改。驚不驚喜~
2.為自定義資料型別(結構體、共用體和列舉型別)定義簡潔的型別名稱
以結構體為例,定義一個名為Point的結構體:
struct Point
{
double x;
double y;
double z;
}; //注意別忘了分號
此時結構體struct Point 為新的資料型別,呼叫這個結構體來定義變數時必須保留字struct,而不能像int 和 double一樣直接使用。當使用的次數多了是不是顯得很麻煩?
呼叫
struct Point oPoint1={100,100,0}; //定義一個結構體oPoint1並初始化
struct Point oPoint2;
用typedef 定義這個結構體,如下:
typedef struct tagPoint //這部分程式碼分成兩部分
{ //(1)定義tagPoint結構體,構成新的結構型別struct tagPoint
double x; //(2)使用typedef為這個結構體取一個別名Point
double y; //即typedef struct tagPoint Point;
double z;
}Point;
另外,這裡做一下延伸,記錄一下可能編譯器會報錯的點:
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode;
上面這個結構體中,錯在哪裡呢?可能有人會覺得錯在結構體中包含了指向自己的指標,但真是這樣嗎?其實,C語言允許結構體中包含指向自己的指標。究其原因,根本問題在於typedef的應用。
在結構體的建立中遇到了pNext宣告,其型別是pNode, 但是結構體本身還沒建立完,編譯器還不認識pNode是誰,所以自然會報錯。那要怎麼改?
typedef struct tagNode
{
char *pItem;
struct tagNode *pNext; //*是跟著結構體的,struct tagNode *
} *pNode;
3.為陣列定義簡潔的型別名稱
typedef int INT_ARRAY_100[100];
INT_ARRAY_100 arr;
4.為指標定義簡潔的名稱
typedef char* PCHAR;
PCHAR pa; //==char* pa
上面的指標比較簡單,使用typedef看起來意義不大,但是遇到複雜的情況,優勢就出來了:
//PFun是我們建立的一個類型別名
typedef int *(*PFun)(int, char*);
//使用定義的新型別來宣告物件,等價於int *(*a[5])(int, char*);
PFun a[5];
ok,關於關鍵詞typedef的用法介紹就到此結束啦,這些內容是看了馬偉先生著的 ‘Writing Solid Code’ 後的一些收穫。要是朋友們有什麼補充的還請不吝賜教~