久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

typedef的用法

 啟蒙彩魂 2010-12-12
typedef在C中是定義數(shù)據(jù)類型別名的,例如typedef int a;則a是與int 具有相同功能的別名,,相當(dāng)于我們說的給一個人起綽號,,其實(shí)他們是同一個人,這里也一樣,,這樣一個定義之后,,a就與int是一回事了
typedef char * a,* b;這里也一個意思啊,,這句話就是定義了char*型的別名a與b,那么a與b就有了與char*相同的功能了,,那么我們?nèi)绻x
a num;則num就被定義為char*型的指針了


關(guān)于typedef的用法
一.基本概念剖析
int* (*a[5])(int, char*);       //#1
void (*b[10]) (void (*)()); //#2
double(*)() (*pa)[9];         //#3

1.C語言中函數(shù)聲明和數(shù)組聲明。函數(shù)聲明一般是這樣:
int fun(int, double);
對應(yīng)函數(shù)指針(pointer to function)的聲明是這樣:
int (*pf)(int, double),;
可以這樣使用:
pf = &fun;       //賦值(assignment)操作
(*pf)(5, 8.9);//函數(shù)調(diào)用操作
也請注意,,C語言本身提供了一種簡寫方式如下:
pf = fun;       // 賦值(assignment)操作
pf(5, 8.9);     // 函數(shù)調(diào)用操作
不過我本人不是很喜歡這種簡寫,它對初學(xué)者帶來了比較多的迷惑,。
數(shù)組聲明一般是這樣:
int a[5],;
對于數(shù)組指針(pointer to array)的聲明是這樣:
int (*pa)[5];
可以這樣使用:
pa = &a;             // 賦值(assignment)操作
int i = (*pa)[2]; // 將a[2]賦值給i,;
2.有了上面的基礎(chǔ),,我們就可以對付開頭的三只紙老虎了!:) 這個時候你需要復(fù)習(xí)一下各種運(yùn)算符的優(yōu)先順序和結(jié)合順序了,順便找本書看看就夠了,。
#1:int* (*a[5])(int, char*);
首先看到標(biāo)識符名a,,“[]”優(yōu)先級大于“*”,a與“[5]”先結(jié)合,。所以a是一個數(shù)組,,這個數(shù)組有5個元素,每一個元素都是一個指針,,
指針指向“(int, char*)”,,對,指向一個函數(shù),,函數(shù)參數(shù)是“int, char*”,,返回值是“int*”,。完畢,,我們干掉了第一個紙老虎。:)
#2:void (*b[10]) (void (*)());
b是一個數(shù)組,,這個數(shù)組有10個元素,,每一個元素都是一個指針,指針指向一個函數(shù),,函數(shù)參數(shù)是“void (*)()”【注1】,,返回值是“void”。完畢,!
注1:這個參數(shù)又是一個指針,,指向一個函數(shù),函數(shù)參數(shù)為空,,返回值是“void”,。
#3:double(*)()(*pa)[9];
pa是一個指針,指針指向一個數(shù)組,,這個數(shù)組有9個元素,,每一個元素都是“double(*)()”【也即一個指針,指向一個函數(shù),,函數(shù)參數(shù)為空,,返回值是“double”】。(注意typedef int* p[9]與typedef int(*p)[9]的區(qū)別,,前者定義一個數(shù)組,,此數(shù)組包含9個int*類型成員,而后者定義一個指向數(shù)組的指針,被指向的數(shù)組包含9個int類型成員),。
現(xiàn)在是不是覺得要認(rèn)識它們是易如反掌,,工欲善其事,必先利其器,!我們對這種表達(dá)方式熟悉之后,,就可以用“typedef”來簡化這種類型聲明。
#1:int* (*a[5])(int, char*);
typedef int* (*PF)(int, char*);//PF是一個類型別名【注2】,。
PF a[5];//跟int* (*a[5])(int, char*);的效果一樣,!
注2:很多初學(xué)者只知道typedef char* pchar;但是對于typedef的其它用法不太了解,。Stephen Blaha對typedef用法做過一個總結(jié):“建立一個類型別名的方法很簡單,,在傳統(tǒng)的變量聲明表達(dá)式里用類型名替代變量名,然后把關(guān)鍵字typedef加在該語句的開頭”,。
#2:void (*b[10])(void (*)());
typedef void (*pfv)();
typedef void (*pf_taking_pfv)(pfv);
pf_taking_pfv b[10]; //跟void (*b[10]) (void (*)());的效果一樣,!
#3. double(*)()(*pa)[9];
typedef double(*PF)();
typedef PF (*PA)[9];
PA pa; //跟doube(*)()(*pa)[9];的效果一樣!
3.const和volatile在類型聲明中的位置,。
在這里我只說const,,volatile是一樣的!【注3】
注3:顧名思義,volatile修飾的量就是很容易變化,,不穩(wěn)定的量,,它可能被其它線程,操作系統(tǒng),,硬件等等在未知的時間改變,,
所以它被存儲在內(nèi)存中,每次取用它的時候都只能在內(nèi)存中去讀取,,它不能被編譯器優(yōu)化放在內(nèi)部寄存器中,。
類型聲明中const用來修飾一個常量,我們一般這樣使用:const在前面:
const int,; //int是const
const char*;//char是const
char* const;//*(指針)是const
const char* const;//char和*都是const
對初學(xué)者,,const char*和 char* const是容易混淆的。這需要時間的歷練讓你習(xí)慣它,。 上面的聲明有一個對等的寫法:const在后面:
int const,; //int是const
char const*;//char是const
char* const;//*(指針)是const
char const* const;//char和*都是const
第一次你可能不會習(xí)慣,但新事物如果是好的,,我們?yōu)槭裁匆芙^它呢,?:)const在后面有兩個好處:
A.const所修飾的類型正好是在它前面的那一個。如果這個好處還不能讓你動心的話,,那請看下一個,!
B.我們很多時候會用到typedef的類型別名定義,。比如typedef char* pchar,如果用const來修飾的話,,
當(dāng)const在前面的時候,,就是const pchar,你會以為它就是const char* ,,但是你錯了,,它的真實(shí)含義是char* const。
是不是讓你大吃一驚,!但如果你采用const在后面的寫法,,意義就怎么也不會變,不信你試試,!
不過,,在真實(shí)項(xiàng)目中的命名一致性更重要。你應(yīng)該在兩種情況下都能適應(yīng),,并能自如的轉(zhuǎn)換,,公司習(xí)慣,
商業(yè)利潤不論在什么時候都應(yīng)該優(yōu)先考慮,!不過在開始一個新項(xiàng)目的時候,,你可以考慮優(yōu)先使用const在后面的習(xí)慣用法。

二.Typedef聲明有助于創(chuàng)建平臺無關(guān)類型,,甚至能隱藏復(fù)雜和難以理解的語法,。
不管怎樣,使用 typedef 能為代碼帶來意想不到的好處,,通過本文你可以學(xué)習(xí)用typedef避免缺欠,從而使代碼更健壯,。
typedef聲明,,簡稱typedef,為現(xiàn)有類型創(chuàng)建一個新的名字,。比如人們常常使用 typedef 來編寫更美觀和可讀的代碼,。
所謂美觀,意指typedef 能隱藏笨拙的語法構(gòu)造以及平臺相關(guān)的數(shù)據(jù)類型,,從而增強(qiáng)可移植性和以及未來的可維護(hù)性,。
本文下面將竭盡全力來揭示 typedef 強(qiáng)大功能以及如何避免一些常見的陷阱,如何創(chuàng)建平臺無關(guān)的數(shù)據(jù)類型,隱藏笨拙且難以理解的語法.
typedef使用最多的地方是創(chuàng)建易于記憶的類型名,,用它來歸檔程序員的意圖,。類型出現(xiàn)在所聲明的變量名字中,位于typedef關(guān)鍵字右邊,。
例如:typedef int size;
此聲明定義了一個 int 的同義字,,名字為 size。注意typedef并不創(chuàng)建新的類型。它僅僅為現(xiàn)有類型添加一個同義字,。
你可以在任何需要 int 的上下文中使用 size:
void measure(size * psz);
size array[4];
size len = file.getlength();
typedef 還可以掩飾復(fù)合類型,,如指針和數(shù)組。例如,,你不用象下面這樣重復(fù)定義有81個字符元素的數(shù)組:
char line[81]; char text[81];
定義一個typedef,,每當(dāng)要用到相同類型和大小的數(shù)組時,,可以這樣:
typedef char Line[81];
Line text, secondline;
getline(text);
同樣,,可以象下面這樣隱藏指針語法:
typedef char * pstr;
int mystrcmp(pstr, pstr);   
這里將帶我們到達(dá)第一個 typedef 陷阱。標(biāo)準(zhǔn)函數(shù) strcmp()有兩個const char *類型的參數(shù),。因此,,它可能會誤導(dǎo)人們象下面這樣聲明:
int mystrcmp(const pstr, const pstr);
這是錯誤的,事實(shí)上,,const pstr被編譯器解釋為char * const(一個指向 char 的常量指針),,而不是const char *(指向常量 char 的指針)。
這個問題很容易解決:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr);
上面討論的 typedef 行為有點(diǎn)像 #define 宏,,用其實(shí)際類型替代同義字,。不同點(diǎn)是typedef在編譯時被解釋
,因此讓編譯器來應(yīng)付超越預(yù)處理器能力的文本替換,。例如:
typedef int (*PF) (const char *, const char *);
這個聲明引入了 PF 類型作為函數(shù)指針的同義字,,該函數(shù)有兩個 const char * 類型的參數(shù)以及一個 int 類型的返回值。如果要使用下列形式的函數(shù)聲明,,那么上述這個 typedef 是不可或缺的:
PF Register(PF pf);
Register()的參數(shù)是一個PF類型的回調(diào)函數(shù),,返回某個函數(shù)的地址,其署名與先前注冊的名字相同,。做一次深呼吸,。下面我展示一下如果不用 typedef,我們是如何實(shí)現(xiàn)這個聲明的:
int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *);
很少有程序員理解它是什么意思,,更不用說這種費(fèi)解的代碼所帶來的出錯風(fēng)險(xiǎn)了,。顯然,這里使用 typedef 不是一種特權(quán),,
而是一種必需,。typedef 就像 auto,extern,,mutable,,static,和 register 一樣,,是一個存儲類關(guān)鍵字,。
這并不是說typedef會真正影響對象的存儲特性,;它只是說在語句構(gòu)成上,typedef 聲明看起來象 static,,extern 等類型的變量聲明,。
下面將帶到第二個陷阱:
typedef register int FAST_COUNTER; // 錯誤編譯通不過
問題出在你不能在聲明中有多個存儲類關(guān)鍵字。因?yàn)榉?typedef 已經(jīng)占據(jù)了存儲類關(guān)鍵字的位置,,
在 typedef 聲明中不能用 register(或任何其它存儲類關(guān)鍵字),。typedef 有另外一個重要的用途,那就是定義機(jī)器無關(guān)的類型,,
例如,,你可以定義一個叫 REAL 的浮點(diǎn)類型,在目標(biāo)機(jī)器上它可以獲得最高的精度:
typedef long double REAL;
在不支持 long double 的機(jī)器上,,該 typedef 看起來會是下面這樣:
typedef double REAL;
并且,,在連 double 都不支持的機(jī)器上,該 typedef 看起來會是這樣:
typedef float REAL;
你不用對源代碼做任何修改,,便可以在每一種平臺上編譯這個使用 REAL 類型的應(yīng)用程序,。唯一要改的是 typedef 本身。
在大多數(shù)情況下,,甚至這個微小的變動完全都可以通過奇妙的條件編譯來自動實(shí)現(xiàn),。不是嗎?
標(biāo)準(zhǔn)庫廣泛地使用 typedef 來創(chuàng)建這樣的平臺無關(guān)類型:size_t,ptrdiff 和 fpos_t 就是其中的例子,。
此外,,象 std::string 和 std::ofstream 這樣的 typedef 還隱藏了長長的,難以理解的模板特化語法,,
例如:basic_string,,allocator> 和 basic_ofstream>。
typedef在C中是定義數(shù)據(jù)類型別名的,,例如typedef int a;則a是與int 具有相同功能的別名,,相當(dāng)于我們說的給一個人起綽號,其實(shí)他們是同一個人,,這里也一樣,這樣一個定義之后,,a就與int是一回事了
typedef char * a,* b,;這里也一個意思啊,這句話就是定義了char*型的別名a與b,那么a與b就有了與char*相同的功能了,,那么我們?nèi)绻x
a num;則num就被定義為char*型的指針了

typedef在C中是定義數(shù)據(jù)類型別名的,,例如typedef int a;則a是與int 具有相同功能的別名,相當(dāng)于我們說的給一個人起綽號,,其實(shí)他們是同一個人,,這里也一樣,,這樣一個定義之后,a就與int是一回事了
typedef char * a,* b,;這里也一個意思啊,,這句話就是定義了char*型的別名a與b,那么a與b就有了與char*相同的功能了,那么我們?nèi)绻x
a num;則num就被定義為char*型的指針了

typedef可以增強(qiáng)程序的可讀性,,以及標(biāo)識符的靈活性,,但它也有“非直觀性”等缺點(diǎn)。

typedef 還可以掩飾符合類型,,如指針和數(shù)組,。例如,你不用象下面這樣重復(fù)定義有 81 個字符元素的數(shù)組:

char line[81]; char text[81];

定義一個 typedef,,每當(dāng)要用到相同類型和大小的數(shù)組時,,可以這樣:

typedef char Line[81]; Line text, secondline; getline(text);

同樣,可以象下面這樣隱藏指針語法:

typedef char * pstr; int mystrcmp(pstr, pstr);

  這里將帶我們到達(dá)第一個 typedef 陷阱,。標(biāo)準(zhǔn)函數(shù) strcmp()有兩個‘const char *’類型的參數(shù),。因此,它可能會誤導(dǎo)人們象下面這樣聲明 mystrcmp():

int mystrcmp(const pstr, const pstr);

  這是錯誤的,,按照順序,,‘const pstr’被解釋為‘char * const’(一個指向 char 的常量指針),而不是‘const char *’(指向常量 char 的指針),。這個問題很容易解決:

typedef const char * cpstr; int mystrcmp(cpstr, cpstr); // 現(xiàn)在是正確的

記?。?/strong>不管什么時候,只要為指針聲明 typedef,,那么都要在最終的 typedef 名稱中加一個 const,,以使得該指針本身是常量,而不是對象,。

代碼簡化
  上面討論的 typedef 行為有點(diǎn)像 #define 宏,,用其實(shí)際類型替代同義字。不同點(diǎn)是 typedef 在編譯時被解釋,,因此讓編譯器來應(yīng)付超越預(yù)處理器能力的文本替換,。例如:

typedef int (*PF) (const char *, const char *);

  這個聲明引入了 PF 類型作為函數(shù)指針的同義字,該函數(shù)有兩個 const char * 類型的參數(shù)以及一個 int 類型的返回值,。如果要使用下列形式的函數(shù)聲明,,那么上述這個 typedef 是不可或缺的:

PF Register(PF pf);

  Register() 的參數(shù)是一個 PF 類型的回調(diào)函數(shù),返回某個函數(shù)的地址,,其署名與先前注冊的名字相同,。做一次深呼吸。下面我展示一下如果不用 typedef,,我們是如何實(shí)現(xiàn)這個聲明的:

int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *);

  很少有程序員理解它是什么意思,,更不用說這種費(fèi)解的代碼所帶來的出錯風(fēng)險(xiǎn)了,。顯然,這里使用 typedef 不是一種特權(quán),,而是一種必需,。持懷疑態(tài)度的人可能會問:“OK,有人還會寫這樣的代碼嗎,?”,,快速瀏覽一下揭示 signal()函數(shù)的頭文件 <csinal>,一個有同樣接口的函數(shù),。

typedef 和存儲類關(guān)鍵字(storage class specifier)
  這種說法是不是有點(diǎn)令人驚訝,,typedef 就像 auto,extern,,mutable,,static,和 register 一樣,,是一個存儲類關(guān)鍵字,。這并是說 typedef 會真正影響對象的存儲特性;它只是說在語句構(gòu)成上,,typedef 聲明看起來象 static,,extern 等類型的變量聲明。下面將帶到第二個陷阱:

typedef register int FAST_COUNTER; // 錯誤

  編譯通不過,。問題出在你不能在聲明中有多個存儲類關(guān)鍵字,。因?yàn)榉?typedef 已經(jīng)占據(jù)了存儲類關(guān)鍵字的位置,在 typedef 聲明中不能用 register(或任何其它存儲類關(guān)鍵字),。

促進(jìn)跨平臺開發(fā)
  typedef 有另外一個重要的用途,,那就是定義機(jī)器無關(guān)的類型,例如,,你可以定義一個叫 REAL 的浮點(diǎn)類型,,在目標(biāo)機(jī)器上它可以i獲得最高的精度:

typedef long double REAL;

在不支持 long double 的機(jī)器上,該 typedef 看起來會是下面這樣:

typedef double REAL;

并且,,在連 double 都不支持的機(jī)器上,,該 typedef 看起來會是這樣: 、

typedef float REAL;

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多