typedef用法


在很多中文(包含翻譯過來的中文)C語言書籍,對typedef含義總結性的一句話就是,重新定義一種數據類型(或者是給類型起別名)。在之前很長的一段時間里,我並不理解它的用法,甚至覺得它沒有#define好。

比如我想簡寫unsigned char,我覺得用#define uchar unsigned char就挺方便的,后來隨着應用越來越復雜,我才感覺到typedef的好處,也慢慢理解它與#define的區別。我們舉以下幾種情況來討論#define與typedef的區別與用法。

1、宏替換,肯定只能用#define了,比如:#define PI 3.14

2、給簡單數據類型起別名:#define uint32 unsigned int  或   typedef unsigned int uint32;其實這兩個是一樣的。

3、聲明一個指向簡單數據類型變量的指針,比如我們這樣定義  #define uint32_p   unsigned int *  如果我們只用來聲明一個指針變量是沒問題的,但是要是出現這樣一種情況:uint32_p  p1,p2;結果會怎樣呢?根據#define替換的功能,可以解析成

unsigned int *p1,p2;而這個聲明的作用與我們之前的目的是完全不一樣了吧。而如果我們換成了typedef unsigned int * uint32_p;uint32_p,是一種新的數據類型,完全可以用它去聲明uint32_p p1,p2;

4、結構體類型的聲明:typedef struct{

                   uint32 a;

                   uint16 *p;

                  uint16 array[10];

                                                           }m_T;        我們可以直接用m_T聲明結構體變量;m_T  m1,*m2;而且我們可以把這個聲明放在一個頭文件里,方便其它想使用這個聲明的地方。這里要是換成用#define實現會怎樣呢?我是沒試過......

5、我們看這樣一個表達式,也是學習指針(函數指針、指針函數)最為經典的例子:(*(void (*)())0)();我們知道void(*)()這是一個函數指針類型的聲明,聲明了一個指向返回值類型為void的函數的函數指針,函數指針指向的函數的地址為0地址,最后(*0)();調用內存地址為0的那個函數,假如我們在程序的其它地方也會用到void (*)(),我們是不是考慮一下,用typedef  void (*A)()當我們再要定義返回值類型為void類型的函數指針時只用寫:A a;,那么最開始的例子就可以寫作:(*(A)0)();其實這里如果換成#define void (*)() A,是不會也能實現這個效果呢?

寫到這里我要借助C陷阱與缺陷里的內容了,請大家自己理解:

使用 typedef 的目的 or 好處:

1、為了使表達式更簡潔,上面的這個例子:(*(void(*)())0)();假如程序里很多地方要用到類型: void(*)() ,我們可以為這種類型起一個別名:typedef void (*A)();,當我們再要定義返回值類型為void類型的函數指針時只用寫:A a;,那么最開始的例子就可以寫作:(*(A)0)();
2、為了隱藏特定類型的實現,強調類型的使用目的
3、允許一種類型用於多個目的,同時使得每次使用給類型的目的明確
如:typedef int (*Function)(const char *, const char *);

該定義表示 Function 是一種指向函數的指針的類型的別名,要使用這種指針類型時只需直接使用 Function即可,不必每次把整個聲明都寫出來

void (*Signal(int,void(*)(int)))(int);

typedef void (*HANDLER)(int);

HANDLER Signal(int,HANDLER);
上下兩種聲明意義是一致的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM