雖然知道 typedef 基本的用法,但是經常碰到一些奇怪的用法(比如用在函數,指針方面的時候)就比較容易糊塗。於是查了下資料後,在這裏做一個總結,歡迎更新和指點。
1,typedef int INTEGER 指定用 INTEGER 代表 int 類型。即以下兩行語句是等價的。
int i;
INTEGER i;
2,typedef struct date
{
int month,day,year;
}DATE,*P; 給結構體date一個新名稱 DATE,並聲明一個指向此結構體類型的指針。此用法如下所示。
#include<stdio.h>
typedef struct node
{
int a;
} NODE,*Pstr;
int main()
{
NODE a;
a.a = 20;
Pstr t = new node;//此時與NODE *t 是等價的。
t->a = 10;
printf("%d %d\n",a.a,t->a);
return 0;
}
3,用typedef 可以聲明數組類型。如以下兩行代碼是等價的。
(1)int a[10],b[10],c[10],d[10];//均是一位數組,大小也相同
(2)typedef int ARR[10]; ARR a,b,c,d;//ARR爲數組類型,它包含10個元素。因此a,b,c,d都被定義爲一維數組,含10個元素
4,當typedef碰到指針,並和const用在一起時。
在string庫裏面,有比較相等的重載函數strcmp(const char *,const char *);若想用一個別名代替char *。比如:typedef char * pstr;
則上面的函數參數變爲strcmp(const pstr ,const pstr)。其實這樣寫是錯誤的!!
const char *p 代表的意思是 p 是一個指向char 的指針常量,所指的內容是不能改變的。而consr pstr 等價於 char * const p,此時所代表的意思是 p 是一個指向char的常量指針,p是不能改變的。
要想用typedef去替換,可以以這種形式:typedef const char * pstr;
5,sigal()是一種系統調用,用於通知運行時系統,在ANSI C標準中,sinnal()的聲明如下:
void ( * signal( int sig, void (* func)(int) )) ( int );
看到這個函數的時候有沒有感覺到頭大?
signal 是一個函數,它返回一個函數指針,這個函數指針所指向的函數接受一個 int 參數並返回 void。
void (* func) ( int );它表示一個函數指針,所指向的函數接受一個 int 參數,返回值是 void。
現在我們用 typedef 來代表通用部分。
typedef void( * ptr_to_func ) ( int );//ptr_to_fun 是一個函數指針,該函數解釋一個 int 參數,返回值爲 void。
prc_to_func signal( int ,pre_to_func );//它表示 signal 是一個函數,它接受兩個參數,其中一個是 int,另一個是 ptr_to_func。返回值是ptr_to_func。
6,當然 typedef 也有缺點,它具有與其他聲明一樣混亂的語法,同樣可以把幾個聲明器放到一個聲明中去。例如:typedef int *pstr,*arr[5]。但是最好不要在一個 typedef 中放幾個聲明器。
7,typedef 與 define 的區別:
(1)typedef 可以看成一種徹底的“封裝”類型——在聲明它之後不能在往裏面增加其它的東西。比如:
#define peach int
unsigned peach i;/*沒問題*/
typedef int banana;
unsigned banana i;/*錯誤,非法*/
(2)在連續幾個變量的聲明中,用 typedef 定義的類型能夠保證所有變量爲同意類型,而 #define 不行。比如:
#define int_ptr int *i
int_ptr chalk,cheese;//相當於 int *chalk,cheese;即chalk 爲指針類型,而cheese爲int類型。
typedef char * char_ptr;
char_ptr Benley,Rolls;//此時兩個變量均爲 char * 類型。