正文`typedef` 的使用
結語今天來介紹 c 語言中typedef
關鍵字的作用。相信用過 c/c++ 的人都知道#define
也能起到型別定義的作用,但是實際上#define
關鍵字只能起到靜態的文字無腦替換的功能;相較之下typedef
更接近宣告表示式的形式,接下來我們就來看看typedef
是怎麼工作的吧。
c++typedef的詳細用法
在使用 typedef 之前,我們先來複習一下 c/c++ 中複雜變數的宣告和相應的指標型別(已經非常熟悉 c/c++ 的型別和函式指標宣告的可以跳過:typedef
的使用):
int i;
// 整數型別,變數名 i
int*ip;
// 整數型別指標,變數名 ip
int*
*ipp;
// 指向整數型別指標的指標,變數名 ipp
然而變數名不一定都出現在宣告表示式的最後
int ia[10]
;// 整數陣列,長度為 10,變數名 ia(同時也是陣列首位址)
int(
*iap)[10
];// 指向長度為 10 的整數陣列的指標,變數名為 iap
// 注意:這裡不能寫成 int *iap[10],因為 的優先順序比 * 高
函式宣告的形式又更難理解了
intf(
);// 無引數、返回 int 型別,函式名 f
int(
*fp)()
;// 指向無引數、返回 int 型別的函式指標,指標名 fp
void
(*fp2)
(int
,int
,float);
// 指向接受三個引數(int, int, float)、返回 void 型別的函式指標,指標名 fp2
double(*
(*fp3)()
)(int)
// 指向無引數,返回乙個函式指標的函式指標,返回的函式指標接受乙個 int 引數、返回 double 型別
到此我們可以看出一些端倪,識別符號的宣告都有先右再左
的共同規則,從識別符號
開始,先向右探,看到)
或(
後調轉方向,讓我們一步步從簡到繁來驗證這個規則:
函式宣告和函式指標也是同理:
最後我們解析兩個 linux 核心**現的型別宣告:
double(*
(*(*fp3)()
)[10]
)();
int(*(
*f4()
)[10]
)();
我們一樣根據先右再左
的法則來解析這兩個型別:
到此是不是對 c/c++ 的複雜型別和函式指標跟了解了,之後看到再複雜的型別只要把握著先右再左
的原則就不怕看不懂了。
然而當我們需要重複使用這種複雜型別的時候,每次都展開來寫的話,**的可讀性將非常低,閱讀**的人需要花費大量時間來重複解析識別符號的型別,這時候就是typedef
派上用場的時候了。
typedef
關鍵字的規則很簡單。當我們將typedef
加到識別符號宣告的表示式前面時,識別符號就成為乙個新的型別:
// 一般的識別符號(變數)
int i =3;
// 識別符號表示新的型別
typedef
int i;
i i =3;
// 以下三種宣告方式一樣
i i(3)
;i(i)=
3;
// 一般變數 person
struct person p;
struct person person;
person =
;p =
;// 定義型別
typedef
struct
person;
// 直接使用型別來宣告結構體變數
person person()
;person
(person2)
=;
// 一般函式宣告
intadd
(int
,int);
intsub
(int
,int);
// 將共同函式型別定義成新型別
typedef
intbinary_func
(int
,int);
typedef
struct
calculator;
int calculator::
add(
int x,
int y)
int calculator::
sub(
int x,
int y)
// 共同形式的函式
voidf(
)voidg(
)int
add(
int x,
int y)
intsub
(int x,
int y)
// 定義一般函式指標
void
(*fp)()
;fp = f;fp(
);// output: function f
fp = g;fp(
);// output: function g
int(
*fp2)
(int
,int);
fp2 = add;
cout <<
fp2(1,
2);// output: 3
fp2 = sub;
cout <<
fp2(1,
2);// output: -1
// 定義乙個函式指標的新型別
typedef
void
(*fp)()
;typedef
int(
*bfp)
(int
,int);
fp fp_f = f, fp_g = g;
fp_f()
;// output: function f
fp_g()
;// output: function g
bfp bfp_add = add, bfp_sub = sub;
cout <<
bfp_add(1
,2);
// output: 3
cout <<
bfp_sub(1
,2);
// output: -1
同理前面提到的複雜型別也能夠構建成乙個新的型別,甚至我們能夠一步步拆解使得型別宣告更平易近人(以double (*(*(*_fp)())[10])()
為例):
typedef
double
(*dfpv)()
;// return double, function pointer, void parameter
typedef dfpv (
*dfpv_ten)[10
];// 指向乙個大小為 10 陣列,元素為上述型別的指標
typedef dfpv_ten (
*fp)()
;double(*
(*(*_fp)()
)[10]
)();
fp fp = _fp;
// 成立,說明 _fp 就是 fp 型別的函式指標
簡而言之,typedef
關鍵字的作用就是幫助我們復用複雜型別的宣告。與一般的常量一樣,我們都知道在程式中不應該出現未經定義的魔數(magic number)
;同理,程式中也不應該到處冒出未經統一定義的野型別,這時我們就可以使用typedef
關鍵字統一宣告接下來要用到的複雜型別,不僅避免野型別的出現,也大大提高程式的可讀性。 typedef定義型別
c語言的2種型別 內建型別與使用者自定義型別 typedef定義型別而非變數 型別是乙個資料模板,變數是乙個實在的資料。型別不佔記憶體,變數佔記憶體 物件導向的語言中 型別就是類class,變數就是物件 typedef與 define巨集的區別 typedef與結構體 結構體在使用時都是先定義結構體...
c語言之使用typedef定義型別
可以用typedef宣告新的型別名來代替已有的型別名。例項1 include include typedef struct student intmain 例項2 include include typedef int num 100 int main printf d n sizeof num s...
typedef定義資料型別
用typedef重新定義資料型別很常用 1.用typedef重新定義普通型別資料。typedef int count 將int重新命名為count typedef float score 將float重新命名為score 2,用typedef將為指標型別重新命名 typedef float poin...