C语言应用笔记:C语言typedef关键字及其使用
C 語言允許用戶使用 typedef 關鍵字來定義自己習慣的數據類型名稱,來替代系統默認的基本類型名稱、數組類型名稱、指針類型名稱與用戶自定義的結構型名稱、共用型名稱、枚舉型名稱等。
一旦用戶在程序中定義了自己的數據類型名稱,就可以在該程序中用自己的數據類型名稱來定義變量的類型、數組的類型、指針變量的類型與函數的類型等。typedef 關鍵字定義的名稱并不是真的創造了一種數據類型,而是給已有的或者復合型的以及復雜的數據類型取一個我們更容易理解識別的別名。
typedef 關鍵字怎么使用?又有哪些情況可以使用?接下來我們就對它的幾種用法進行說明:
(1)基本數據類型定義
也就是說,我們使用 typedef 關鍵字對系統默認的基本數據類型名進行重新定義。例如我們使用標準整數的數據類型 uint8_t 和 uint16_t 等時,其實它們的原始定義如下:
typedef?unsigned?char?uint8_t;???//無符號8位整數 typedef?signed?char?int8_t;??????//有符號8位整數 typedef?unsigned?short?uint16_t;?//無符號16位整數 typedef?signed?short?int16_t;????//有符號16位整數 typedef?unsigned?long?uint32_t;??//無符號32位整數 typedef?signed?long?int32_t;?????//有符號32位整數顯然,使用 typedef 關鍵字給已有的數據類型定義了一個別名。當我們使用 uint8_t 時,就和使用 unsigned char 是一樣的。此外,我們還可以使用這種方法來定義與平臺無關的類型,這樣,當跨平臺移植程序時,我們只需要修改一下 typedef 的定義即可,而不用對其他源代碼做任何修改。
(2)指針數據類型定義
有些時候我們也會使用 typedef 關鍵字定義指針數據類型,用來簡化我們所使用的指針變量的聲明,例如:
typedef?int?*pointer; typedef?int?(*pointer)[N]; typedef?int?array[M][N];上面的第1個例子中,我們定義了一個指針類型,當我們使用 pointer p 聲明一個指針變量,就和使用 int *p 的含義是一樣的。這個例子是一個指針變量類型,可以演化出很多用法,如定義數組對象可以更明確。有時候,我們也定義指向二維數組的指針,使用 typedef 關鍵字就可以使得操作更符合我們的常規認知。第2個例子中的 pointer 等價于 int (*)[N],當我們聲明 pointer p 就相當于 int (*a)[N]。第3個例子的含義與指針是類似的,比如我們定義 array a 就是聲明了一個 M 行 N 列的數組,此時 p = a 是可以的。
我們考慮到數組很多時候可以使用指針表示,所以將其放在一起討論,而其他一些對象指針我們單獨討論。其實,不光是上述數組和指針可以使用 typedef 關鍵字定義別名,其他如:一維和多維數組,指針數組等都可以這樣使用。
(3)用戶對象類型定義
這里的用戶對象是指結構體、聯合體以及枚舉等用戶自定義的數據類型。我們可以使用 typedef 關鍵字給結構體等類型定義一個別名,這樣我們可以在多個地方更方便地使用它。例如,使用 typedef 關鍵字為結構體類型定義一個別名:
typedef?struct {??float?Kp;?//比例系數????float?Ki;?//積分系數????float?Kd;?//微分系數????????float?Error;?????//本次誤差????float?LastError;?//上一次誤差????float?Diff;??????//PID微分項????????float?Integral;????//PID積分項????float?MaxIntegral;?//積分上限????float?MinIntegral;?//積分下限????????float?Output;????//PID輸出項????float?MaxOutput;?//輸出上限????float?MinOutput;?//輸出下限 }?PID_TypeDef;這樣我們在需要使用結構體類型定義一個對象時,我們可以使用 PID_TypeDef 定義就可以與原始定義相同了,例如:
PID_TypeDef?vPID;同樣我們也可以使用 typedef 關鍵字為枚舉定義一個別名:
typedef?enum {?WRITE_REG?=?((uint8_t)0x80),?//寫寄存器功能碼????READ_REG?=?((uint8_t)0x81),??//讀寄存器功能碼????WRITE_VAR?=?((uint8_t)0x82),?//寫變量功能碼????READ_VAR?=?((uint8_t)0x83)???//讀變量功能碼 }?FunctionCode;我們需要定義枚舉變量時,也是使用 FunctionCode fc 就可以了。當然,我們也可以使用定義的類型聲明指針變量,或者直接有 typedef 關鍵字定義指向對象的指針類型,如定義結構體指針類型。
(4)函數類型定義
typedef 關鍵字也常用來定義函數類型,用以聲明同類型的函數或者函數指針變量。這一種類型定義的函數用作形參等回調的方式使用時,非常有用,具體用法可參考回調函數的使用。
使用 typedef 關鍵字定義函數類型與前面的各種方式類似。例如:
typedef?int?fType(void);這里 fType 等價于 int (void) 類型函數。如果我們使用 fType function 聲明函數 function 時,與使用 int function(void) 來聲明是一樣的。
同樣我們也可以使用 fType 來定義函數指針。如果我們使用 fType *fPointer 聲明函數指針 fPointer 時,和使用 int (*fPoniter)(void) 來聲明是一樣的。
當然,我們也可以使用 typedef 關鍵字直接定義函數指針類型。例如:
typedef?int?(*fPointer)(void);這樣我們就可以使用 fPointer 來定義一個函數指針。比如我們使用 fPointer fp 聲明函數指針就如同使用 int (*fp)(void) 來聲明。
(5)typedef 關鍵字與宏定義
前面我們已經簡要說了 typedef 關鍵字的基本用法,我們發現它的功能似乎宏定義也能實現,所以我們接下來看一下 typedef 關鍵字和 #define 定義的宏之間究竟有何不同。
從功能范圍來講,typedef 主要是為已經存在的關鍵字或者類型及其組合取一個我們容易識別的別名。在這一點上 #define 也可以實現,但除此之外 #define 還有其他用處,如果愿意的話你可以使用它定義任何代碼,這是 typedef 所不具備的。
從執行時間來講,對于 #define 定義的宏,其在預處理階段就會被替換,而 typedef 定義的類型會在編譯時處理。
從作用域上來講,一般來說 #define 定義的宏沒有作用域的限制,只要在使用前定義就可以,而 typedef 定義的別名是有作用域的。
從實現效果來講,我們使用 typedef 定義一個指針類型,然后使用該類型可以同時聲明多個變量,而 #define 卻不是這樣的。例如,typedef (int*) pType; 可以使用pType a, b; 這里 a 和 b 都是指向整數的指針變量。但我們同樣定義 #define pType int*, 若使用 pType a, b; 定義 a 和 b,則 a 是指向整數的指針變量,而 b 不是。
還需要特別注意的是,雖然 typedef 并不真正影響對象的存儲特性,但在語法上它還是一個存儲類的關鍵字,就像 auto、extern、static 和 register 等關鍵字一樣。因此,像下面這種聲明方式是不可行的:
typedef?static?int?INT_STATIC;原因是不能聲明多個存儲類關鍵字,由于 typedef 已經占據了存儲類關鍵字的位置,因此,在 typedef 聲明中就不能夠再使用 static 或任何其他存儲類關鍵字了。
聲明:
本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。
總結
以上是生活随笔為你收集整理的C语言应用笔记:C语言typedef关键字及其使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ads抗ddos(ads防ddos攻击)
- 下一篇: 羊了个羊安卓修改教程(安卓修改教程)