C語言typedef詳解

2022-04-04 04:46:10 字數 4040 閱讀 7882

c語言允許使用者使用 typedef 關鍵字來定義自己習慣的資料型別名稱,來替代系統預設的基本型別名稱、陣列型別名稱、指標型別名稱與使用者自定義的結構型名稱、共用型名稱、列舉型名稱等。一旦使用者在程式中定義了自己的資料型別名稱,就可以在該程式中用自己的資料型別名稱來定義變數的型別、陣列的型別、指標變數的型別與函式的型別等。

例如,c 語言在 c99 之前並未提供布林型別,但我們可以使用 typedef 關鍵字來定義乙個簡單的布林型別,如下面的**所示:

typedef int bool;

#define true 1

#define false 0

定義好之後,就可以像使用基本型別資料一樣使用它了,如下面的**所示:

boolbflag=true;

在實際使用中,typedef 的應用主要有如下4種。

1) 為基本資料型別定義新的型別名

也就是說,系統預設的所有基本型別都可以利用 typedef 關鍵字來重新定義型別名,示例**如下所示:

typedef unsigned int count;

而且,我們還可以使用這種方法來定義與平台無關的型別。比如,要定義乙個叫 real 的浮點型別,在目標平台一上,讓它表示最高精度的型別,即:

typedef long double real;

在不支援 long double 的平台二上,改為:

typedef double real;

甚至還可以在連 double 都不支援的平台三上,改為:

typedef float real;

這樣,當跨平台移植程式時,我們只需要修改一下 typedef 的定義即可,而不用對其他源**做任何修改。其實,標準庫中廣泛地使用了這個技巧,比如 size_t 在 vc++2010 的 crtdefs.h 檔案中的定義如下所示:

#ifndef _size_t_defined

#ifdef _win64

typedef unsigned __int64size_t;

#else

typedef _w64 unsigned int size_t;

#endif

#define _size_t_defined

#endif

2) 為自定義資料型別(結構體、共用體和列舉型別)定義簡潔的型別名稱

以結構體為例,下面我們定義乙個名為 point 的結構體:

structpoint

;在呼叫這個結構體時,我們必須像下面的**這樣來呼叫這個結構體:

structpoint opoint1=;

structpoint opoint2;

在這裡,結構體 struct point 為新的資料型別,在定義變數的時候均要向上面的呼叫方法一樣有保留字 struct,而不能像 int 和 double 那樣直接使用 point 來定義變數。現在,我們利用 typedef 定義這個結構體,如下面的**所示:

typedef structtagpoint

point;

在上面的**中,實際上完成了兩個操作:

1、定義了乙個新的結構型別,**如下所示:

structtagpoint

;其中,struct 關鍵字和 tagpoint 一起構成了這個結構型別,無論是否存在 typedef 關鍵字,這個結構都存在。

2、使用 typedef 為這個新的結構起了乙個別名,叫 point,即:

typedef structtagpoint point

因此,現在你就可以像 int 和 double 那樣直接使用 point 定義變數,如下面的**所示:

pointopoint1=;

pointopoint2;

為了加深對 typedef 的理解,我們再來看乙個結構體例子,如下面的**所示:

typedef structtagnode

*pnode;

從表面上看,上面的示例**與前面的定義方法相同,所以應該沒有什麼問題。但是編譯器卻報了乙個錯誤,為什麼呢?莫非 c 語言不允許在結構中包含指向它自己的指標?

其實問題並非在於 struct 定義的本身,大家應該都知道,c 語言是允許在結構中包含指向它自己的指標的,我們可以在建立鍊錶等資料結構的實現上看到很多這類例子。那問題在**呢?其實,根本問題還是在於 typedef 的應用。

在上面的**中,新結構建立的過程中遇到了 pnext 宣告,其型別是 pnode。這裡要特別注意的是,pnode 表示的是該結構體的新別名。於是問題出現了,在結構體型別本身還沒有建立完成的時候,編譯器根本就不認識 pnode,因為這個結構體型別的新別名還不存在,所以自然就會報錯。因此,我們要做一些適當的調整,比如將結構體中的 pnext 宣告修改成如下方式:

typedef structtagnode

*pnode;

或者將 struct 與 typedef 分開定義,如下面的**所示:

typedef structtagnode *pnode;

structtagnode

;在上面的**中,我們同樣使用 typedef 給乙個還未完全宣告的型別 tagnode 起了乙個新別名。不過,雖然 c 語言編譯器完全支援這種做法,但不推薦這樣做。建議還是使用如下規範定義方法:

structtagnode

;typedef structtagnode *pnode;

3) 為陣列定義簡潔的型別名稱

它的定義方法很簡單,與為基本資料型別定義新的別名方法一樣,示例**如下所示:

typedef int int_array_100[100];

int_array_100arr;

4) 為指標定義簡潔的名稱

對於指標,我們同樣可以使用下面的方式來定義乙個新的別名:

typedef char* pchar;

pcharpa;

對於上面這種簡單的變數宣告,使用 typedef 來定義乙個新的別名或許會感覺意義不大,但在比較複雜的變數宣告中,typedef 的優勢馬上就體現出來了,如下面的示例**所示:

int *(*a[5])(int,char*);

對於上面變數的宣告,如果我們使用 typdef 來給它定義乙個別名,這會非常有意義,如下面的**所示:

// pfun是我們建立的乙個型別別名

typedef int *(*pfun)(int,char*);

// 使用定義的新型別來宣告物件,等價於int*(*a[5])(int,char*);

pfuna[5];

接下來看乙個簡單的 typedef 使用示例,如下面的**所示:

typedef char* pchar;

int strcmp(const pchar,const pchar);

在上面的**中,「const pchar」 是否相當於 「const char*」 呢?

答案是否定的,原因很簡單,typedef 是用來定義一種型別的新別名的,它不同於巨集,不是簡單的字串替換。因此,「const pchar」中的 const 給予了整個指標本身常量性,也就是形成了常量指標「char*const(乙個指向char的常量指標)」。即它實際上相當於「char*const」,而不是「const char*(指向常量 char 的指標)」。當然,要想讓 const pchar 相當於 const char* 也很容易,如下面的**所示:

typedef const char* pchar;

int strcmp(pchar,pchar);

其實,無論什麼時候,只要為指標宣告 typedef,那麼就應該在最終的 typedef 名稱中加乙個 const,以使得該指標本身是常量。

還需要特別注意的是,雖然 typedef 並不真正影響物件的儲存特性,但在語法上它還是乙個儲存類的關鍵字,就像 auto、extern、static 和 register 等關鍵字一樣。因此,像下面這種宣告方式是不可行的:

typedef static int int_static;

不可行的原因是不能宣告多個儲存類關鍵字,由於 typedef 已經佔據了儲存類關鍵字的位置,因此,在 typedef 宣告中就不能夠再使用 static 或任何其他儲存類關鍵字了。當然,編譯器也會報錯,如在 vc++2010 中的報錯資訊為「無法指定多個儲存類」。

關於typedef的用法總結

typedef用法總結之續

C語言typedef詳解

在c還是c 中,typedef都使用的很多。typedef與 define有些相似,其實是不同的。基本定義 typedef為c語言的關鍵字,作用是為一種資料型別定義乙個新名字,這裡的資料型別包括基本資料型別 int,char 也包括自定義的資料型別 struct 教科書上的解釋為 資料結構的表示 儲...

C語言typedef詳解

在c還是c 中,typedef都使用的很多。typedef與 define有些相似,其實是不同的。基本定義 typedef為c語言的關鍵字,作用是為一種資料型別定義乙個新名字,這裡的資料型別包括基本資料型別 int,char 也包括自定義的資料型別 struct 1 與 define的區別 type...

C語言之typedef詳解

typedef可以看作type define的縮寫,顧名思義就是型別定義,也就是說它只是給已有的型別重新定義了乙個方便使用的別名,並沒有產生新的資料型別。typedef的使用與巨集定義define有些許的相似,但兩者又有以下不同 1.與 define不同,typedef給出的符號名稱僅限於對型別,而...