typedefstruct用法詳解和用法小結(jié)_第1頁
typedefstruct用法詳解和用法小結(jié)_第2頁
typedefstruct用法詳解和用法小結(jié)_第3頁
typedefstruct用法詳解和用法小結(jié)_第4頁
typedefstruct用法詳解和用法小結(jié)_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、1. 基本解釋typedef 為 C語言的關(guān)鍵字,作用是為一種數(shù)據(jù)類型定義一個(gè)新名字。這里的數(shù)據(jù)類型包括內(nèi)部數(shù)據(jù)類型(int,char等)和自定義的數(shù)據(jù)類型(struct等)。在編程中使用 typedef 目的一般有兩個(gè),一個(gè)是給變量一個(gè)易記且意義明確的新名字,另一個(gè)是簡化一些比較復(fù)雜的類型聲明。至于 typedef有什么微妙之處,請你接著看下面對(duì)幾個(gè)問題的具體闡述。2. typedef &結(jié)構(gòu)的問題當(dāng)用下面的代碼定義一個(gè)結(jié)構(gòu)時(shí),編譯器報(bào)了一個(gè)錯(cuò)誤, 為什么呢莫非 C語言不允許在結(jié)構(gòu)中包含指向它自己的指針嗎請你先猜想一下,然后看下文說明:typedef struct tagNodechar *

2、pItem;pNode pNext; *pNode;答案與分析:1、typedef 的最簡單使用typedef long byte_4;給已知數(shù)據(jù)類型long 起個(gè)新名字,叫 byte_4 。2、 typedef與結(jié)構(gòu)結(jié)合使用typedef struct tagMyStructint iNum;long lLength; MyStruct;這語句實(shí)際上完成兩個(gè)操作:1) 定義一個(gè)新的結(jié)構(gòu)類型struct tagMyStructint iNum;long lLength;分析:tagMyStruct 稱為“ tag ”,即“標(biāo)簽”, 實(shí)際上是一個(gè)臨時(shí)名字, struct 關(guān)鍵字和 tagMySt

3、ruct 一起,構(gòu)成了這個(gè)結(jié)構(gòu)類型,不論是否有 typedef ,這個(gè)結(jié)構(gòu)都存在。我們可以用struct tagMyStruct varName來定義變量,但要注意,使用tagMyStruct varName來定義變量是不對(duì)的,因?yàn)閟truct和 tagMyStruct合在一起才能表示一個(gè)結(jié)構(gòu)類型。2) typedef 為這個(gè)新的結(jié)構(gòu)起了一個(gè)名字,叫 MyStruct 。typedef struct tagMyStruct MyStruct;因此, MyStruct 實(shí)際上相當(dāng)于 struct tagMyStruct,我們可以使用 MyStructvarName來定義變量。答案與分析C語言當(dāng)然

4、允許在結(jié)構(gòu)中包含指向它自己的指針,我們可以在建立鏈表等數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)上看到無數(shù)這樣的例子,上述代碼的根本問題在于typedef的應(yīng)用。根據(jù)我們上面的闡述可以知道: 新結(jié)構(gòu)建立的過程中遇到了 pNext 域的聲明,類型是 pNode,要知道 pNode表示的是類型的新名字,那么在類型本身還沒有建立完成的時(shí)候,這個(gè)類型的新名字也還不存在, 也就是說這個(gè)時(shí)候編譯器根本不認(rèn)識(shí) pNode。解決這個(gè)問題的方法有多種:1) 、typedef struct tagNodechar *pItem;struct tagNode *pNext; *pNode;2) 、typedef struct tagNode

5、*pNode;struct tagNodechar *pItem;pNode pNext;注意:在這個(gè)例子中,你用typedef給一個(gè)還未完全聲明的類型起新名字。C 語言編譯器支持這種做法。3) 、規(guī)范做法:typedef uint32 (* ADM_READDATA_PFUNC)( uint16*, uint32 );這個(gè)以前沒有看到過 , 個(gè)人認(rèn)為是宇定義一個(gè)uint32的指針函數(shù) ,uint16*,uint32 為函數(shù)里的兩個(gè)參數(shù) ; 應(yīng)該相當(dāng)于 #define uint32 (* ADM_READDATA_PFUNC)( uint16*, uint32 );struct在代碼中常見兩種

6、形式:struct A;struct A;這其實(shí)是兩個(gè)完全不同的用法:前者叫做“結(jié)構(gòu)體類型定義”,意思是:定義 中的結(jié)構(gòu)為一個(gè)名稱是“A”的結(jié)構(gòu)體。這種用法在 typedef中一般是:typedef struct tagA .A;. A; .x1;和 typedef struct _x2 . x2;有什么不同其實(shí) ,前者是定義了類 _x1 和_x1 的對(duì)象實(shí)例 x1,后者是定義了類 _x2 和 _x2 的類別名 x2 ,所以它們在使用過程中是有取別的. 請看實(shí)例 1.知識(shí)點(diǎn)結(jié)構(gòu)也是一種數(shù)據(jù)類型 ,可以使用結(jié)構(gòu)變量 ,因此 ,象其它類型的變量一樣 ,在使用結(jié)構(gòu)變量時(shí)要先對(duì)其定義。定義結(jié)構(gòu)變量的一

7、般格式為:struct結(jié)構(gòu)名類型 變量名 ;類型 變量名 ;. 結(jié)構(gòu)變量 ;結(jié)構(gòu)名是結(jié)構(gòu)的標(biāo)識(shí)符不是變量名。另一種常用格式為 :typedef struct結(jié)構(gòu)名類型 變量名 ;類型 變量名 ;. 結(jié)構(gòu)別名 ;另外注意 :在 C 中, struct不能包含函數(shù)。在C+中,對(duì) struct進(jìn)行了擴(kuò)展,可以包含函數(shù)。=實(shí)例 1:#include using namespace std;typedef struct _pointint x;int y;point;為什么原聲明: int *(*a5)(int, char*);變量名為 a,直接用一個(gè)新別名pFun 替換 a 就可以了:typedef

8、int *(*pFun)(int, char*);原聲明的最簡化版:pFun a5;2.原聲明: void (*b10) (void (*)();變量名為 b,先替換右邊部分括號(hào)里的,pFunParam為別名一:typedef void (*pFunParam)();再替換左邊的變量b,pFunx 為別名二:typedef void (*pFunx)(pFunParam);原聲明的最簡化版:pFunx b10;3.原聲明: doube(*)() (*e)9;變量名為 e,先替換左邊部分, pFuny 為別名一:typedef double(*pFuny)();再替換右邊的變量e,pFunPar

9、amy為別名二typedef pFuny (*pFunParamy)9;原聲明的最簡化版:pFunParamy e;理解復(fù)雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個(gè)圓括號(hào)就調(diào)轉(zhuǎn)閱讀的方向;括號(hào)內(nèi)分析完就跳出括號(hào),還是按先右后左的順序,如此循環(huán),直到整個(gè)聲明分析完。舉例:int (*func)(int *p);首先找到變量名func ,外面有一對(duì)圓括號(hào),而且左邊是一個(gè)* 號(hào),這說明 func是一個(gè)指針;然后跳出這個(gè)圓括號(hào),先看右邊,又遇到圓括號(hào),這說明(*func)是一個(gè)函數(shù),所以func 是一個(gè)指向這類函數(shù)的指針,即函數(shù)指針,這類函數(shù)具有 int* 類型的形參,返回值類型

10、是int 。int (*func5)(int *);func 右邊是一個(gè) 運(yùn)算符,說明 func 是具有 5 個(gè)元素的數(shù)組; func 的左邊有一個(gè) * ,說明 func 的元素是指針(注意這里的 * 不是修飾 func ,而是修飾 func5 的,原因是 運(yùn)算符優(yōu)先級(jí)比 * 高,func 先跟 結(jié)合) 。跳出這個(gè)括號(hào), 看右邊,又遇到圓括號(hào),說明 func 數(shù)組的元素是函數(shù)類型的指針, 它指向的函數(shù)具有 int* 類型的形參,返回值類型為 int 。也可以記住 2 個(gè)模式:type (*)(.)函數(shù)指針type (*)數(shù)組指針第二、兩大陷阱陷阱一:記住, typedef 是定義了一種類型的新

11、別名,不同于宏,它不是簡單的字符串替換。比如:先定義:typedef char* PSTR;然后:int mystrcmp(const PSTR, const PSTR);const PSTR實(shí)際上相當(dāng)于 const char* 嗎不是的,它實(shí)際上相當(dāng)于char* const 。原因在于 const 給予了整個(gè)指針本身以常量性,也就是形成了常量指針char*const 。簡單來說,記住當(dāng)const 和 typedef 一起出現(xiàn)時(shí), typedef不會(huì)是簡單的字符串替換就行。陷阱二:typedef 在語法上是一個(gè) 存儲(chǔ) 類的關(guān)鍵字(如 auto 、extern 、mutable 、static

12、、 register 等一樣),雖然它并不真正影響對(duì)象的 存儲(chǔ) 特性,如:typedef static int INT2; /不可行編譯將失敗,會(huì)提示“指定了一個(gè)以上的存儲(chǔ)類”。以上資料出自:作者:赤龍第三、 typedef與 #define的區(qū)別案例一:通常講, typedef 要比 #define要好,特別是在有指針的場合。請看例子:typedef char *pStr1;#define pStr2 char *;pStr1 s1, s2;pStr2 s3, s4;在上述的變量定義中, s1、s2、 s3 都被定義為 char * ,而 s4 則定義成了 char ,不是我們所預(yù)期的指針變

13、量,根本原因就在于 #define只是簡單的字符串替換而typedef 則是為一個(gè)類型起新名字。案例二:下面的代碼中編譯器會(huì)報(bào)一個(gè)錯(cuò)誤,你知道是哪個(gè)語句錯(cuò)了嗎t(yī)ypedef char * pStr;char string4 = abc;const char *p1 = string;const pStr p2 = string;p1+;p2+;是 p2+出錯(cuò)了。這個(gè)問題再一次提醒我們: typedef 和 #define 不同,它不是簡單的文本替換。上述代碼中 const pStr p2 并不等于 const char * p2。const pStr p2 和 const long x 本質(zhì)上

14、沒有區(qū)別,都是對(duì)變量進(jìn)行只讀限制,只不過此處變量 p2 的數(shù)據(jù)類型是我們自己定義的而不是系統(tǒng)固有類型而已。因此,const pStrp2 的含義是:限定數(shù)據(jù)類型為char *的變量p2 為只讀,因此p2+錯(cuò)誤。第四部分資料:使用typedef抑制劣質(zhì)代碼摘要: Typedef 聲明有助于創(chuàng)建平臺(tái)無關(guān)類型,甚至能隱藏復(fù)雜和難以理解的語法。不管怎樣,使用 typedef 能為代碼帶來意想不到的好處,通過本文你可以學(xué)習(xí)用 typedef 避免缺欠,從而使代碼更健壯。typedef聲明,簡稱 typedef ,為現(xiàn)有類型創(chuàng)建一個(gè)新的名字。比如人們常常使用 typedef 來編寫更美觀和可讀的代碼。 所

15、謂美觀,意指 typedef 能隱藏笨拙的語法構(gòu)造以及平臺(tái)相關(guān)的數(shù)據(jù)類型,從而增強(qiáng)可移植性和以及未來的可維護(hù)性。本文下面將竭盡全力來揭示 typedef 強(qiáng)大功能以及如何避免一些常見的陷阱。Q:如何創(chuàng)建平臺(tái)無關(guān)的數(shù)據(jù)類型,隱藏笨拙且難以理解的語法A: 使用 typedefs為現(xiàn)有類型創(chuàng)建同義字。定義易于記憶的類型名typedef使用最多的地方是創(chuàng)建易于記憶的類型名,用它來歸檔程序員的意圖。類型出現(xiàn)在所聲明的變量名字中,位于typedef關(guān)鍵字右邊。例如:typedef int size;此聲明定義了一個(gè)int的同義字,名字為size 。注意typedef并不創(chuàng)建新的類型。 它僅僅為現(xiàn)有類型添加

16、一個(gè)同義字。你可以在任何需要 int的上下文中使用size :void measure(size* psz);size array4;sizelen = ();std:vectorvs; typedef還可以掩飾符合類型,如指針和數(shù)組。例如,你不用象下面這樣重復(fù)定義有 81 個(gè)字符元素的數(shù)組:char line81;chartext81;定義一個(gè) typedef,每當(dāng)要用到相同類型和大小的數(shù)組時(shí),可以這樣:typedef char Line81; Line text, secondline;getline(text);同樣,可以象下面這樣隱藏指針語法:typedef char * pstr;i

17、nt mystrcmp(pstr, pstr);這里將帶我們到達(dá)第一個(gè)typedef陷阱。標(biāo)準(zhǔn)函數(shù)strcmp()有兩個(gè) const char * 類型的參數(shù)。因此,它可能會(huì)誤導(dǎo)人們象下面這樣聲明mystrcmp():int mystrcmp(const pstr, const pstr);這是錯(cuò)誤的,按照順序,constpstr 被解釋為 char * const (一個(gè)指向 char的常量指針),而不是 constchar * (指向常量char的指針)。這個(gè)問題很容易解決:typedef const char * cpstr; int mystrcmp(cpstr, cpstr); /現(xiàn)

18、在是正確的記?。?不管什么時(shí)候,只要為指針聲明 typedef ,那么都要在最終的 typedef 名稱中加一個(gè) const ,以使得該指針本身是常量,而不是對(duì)象。代碼簡化上面討論的 typedef 行為有點(diǎn)像 #define 宏,用其實(shí)際類型替代同義字。不同點(diǎn)是 typedef 在編譯時(shí)被解釋,因此讓編譯器來應(yīng)付超越預(yù)處理器能力的文本替換。例如:typedef int (*PF) (const char *, const char *);這個(gè)聲明引入了PF 類型作為函數(shù)指針的同義字,該函數(shù)有兩個(gè)constchar * 類型的參數(shù)以及一個(gè)int類型的返回值。如果要使用下列形式的函數(shù)聲明,那么上

19、述這個(gè)typedef是不可或缺的:PF Register(PFpf);Register()的參數(shù)是一個(gè) PF 類型的回調(diào)函數(shù),返回某個(gè)函數(shù)的地址, 其署名與先前注冊的名字相同。做一次深呼吸。 下面我展示一下如果不用 typedef,我們是如何實(shí)現(xiàn)這個(gè)聲明的:int (*Register (int (*pf)(const char *, const char *) (const char *,const char *); 很少有程序員理解它是什么意思,更不用說這種費(fèi)解的代碼所帶來的出錯(cuò)風(fēng)險(xiǎn)了。顯然,這里使用 typedef 不是一種特權(quán),而是一種必需。持懷疑態(tài)度的人可能會(huì)問: “OK,有人還會(huì)寫這樣的代碼嗎”, 快速瀏覽一下揭示 signal() 函數(shù)的頭文件 ,一個(gè)有同樣接口的函數(shù)。typedef和存儲(chǔ)類關(guān)鍵字( storage class specifier)這種說法是不是有點(diǎn)令人驚訝,typedef就像 auto , extern ,mutable ,static,和 register一樣,是一個(gè)存儲(chǔ)類關(guān)鍵字。這并是說typedef會(huì)真正影響對(duì)象的存儲(chǔ)特性; 它只是說在語句構(gòu)成上, typedef 聲明看起來象 static , extern 等類型的變量

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論